passenger 5.1.12 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +18 -1
- data/Rakefile +4 -1
- data/build/agent.rb +2 -2
- data/build/apache2.rb +17 -10
- data/build/basics.rb +18 -4
- data/build/common_library.rb +7 -3
- data/build/cxx_tests.rb +2 -7
- data/build/misc.rb +3 -1
- data/build/nginx.rb +11 -5
- data/build/oxt_tests.rb +0 -3
- data/build/packaging.rb +3 -2
- data/build/schema_printer.rb +103 -0
- data/build/support/cplusplus.rb +2 -2
- data/build/support/cxx_dependency_map.rb +2575 -868
- data/dev/ci/lib/functions.sh +1 -1
- data/dev/ci/lib/set-container-envvars.sh +1 -1
- data/dev/ci/lib/setup-container.sh +1 -1
- data/dev/ci/run-tests-natively +1 -1
- data/dev/ci/run-tests-with-docker +1 -1
- data/dev/ci/scripts/debug-console-wrapper.sh +1 -1
- data/dev/ci/scripts/docker-entrypoint-stage2.sh +1 -1
- data/dev/ci/scripts/docker-entrypoint.sh +1 -1
- data/dev/ci/scripts/inituidgid +1 -1
- data/dev/ci/scripts/run-tests-natively-stage2.sh +1 -1
- data/dev/ci/scripts/setup-host-natively.sh +1 -1
- data/dev/ci/setup-host +1 -1
- data/dev/ci/tests/apache2/run +1 -1
- data/dev/ci/tests/apache2/setup +1 -1
- data/dev/ci/tests/cxx/run +1 -1
- data/dev/ci/tests/cxx/setup +1 -1
- data/dev/ci/tests/debian/Jenkinsfile +0 -1
- data/dev/ci/tests/debian/run +1 -1
- data/dev/ci/tests/nginx-dynamic/run +1 -1
- data/dev/ci/tests/nginx-dynamic/setup +1 -1
- data/dev/ci/tests/nginx/run +1 -1
- data/dev/ci/tests/nginx/setup +1 -1
- data/dev/ci/tests/nodejs/run +1 -1
- data/dev/ci/tests/nodejs/setup +1 -1
- data/dev/ci/tests/rpm/run +1 -1
- data/dev/ci/tests/ruby/run +1 -1
- data/dev/ci/tests/ruby/setup +1 -1
- data/dev/ci/tests/source-packaging/run +1 -1
- data/dev/ci/tests/source-packaging/setup +1 -1
- data/dev/ci/tests/standalone/run +1 -1
- data/dev/ci/tests/standalone/setup +1 -1
- data/dev/configkit-schemas/index.json +1708 -0
- data/dev/configkit-schemas/update_schema_inline_comments.rb +118 -0
- data/dev/copy_boost_headers +13 -1
- data/dev/index_cxx_dependencies.rb +20 -7
- data/dev/vagrant/provision.sh +1 -1
- data/resources/mime.types +1 -0
- data/resources/templates/standalone/http.erb +1 -6
- data/src/agent/Core/AdminPanelConnector.h +550 -0
- data/src/agent/Core/ApiServer.h +159 -97
- data/src/agent/Core/ApplicationPool/Group.h +2 -0
- data/src/agent/Core/ApplicationPool/Group/InternalUtils.cpp +3 -2
- data/src/agent/Core/ApplicationPool/Group/StateInspection.cpp +109 -0
- data/src/agent/Core/ApplicationPool/Implementation.cpp +5 -3
- data/src/agent/Core/ApplicationPool/Options.h +5 -6
- data/src/agent/Core/ApplicationPool/Pool.h +59 -2
- data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
- data/src/agent/Core/ApplicationPool/Pool/InitializationAndShutdown.cpp +2 -2
- data/src/agent/Core/ApplicationPool/Pool/Miscellaneous.cpp +6 -0
- data/src/agent/Core/ApplicationPool/Pool/StateInspection.cpp +129 -0
- data/src/agent/Core/Config.h +475 -0
- data/src/agent/Core/ConfigChange.cpp +349 -0
- data/src/agent/Core/ConfigChange.h +54 -0
- data/src/agent/Core/Controller.h +35 -3
- data/src/agent/Core/Controller/CheckoutSession.cpp +1 -1
- data/src/agent/Core/Controller/Config.cpp +0 -2
- data/src/agent/Core/Controller/Config.h +168 -104
- data/src/agent/Core/Controller/ForwardResponse.cpp +1 -1
- data/src/agent/Core/Controller/InitRequest.cpp +14 -15
- data/src/agent/Core/Controller/InitializationAndShutdown.cpp +34 -44
- data/src/agent/Core/Controller/Request.h +0 -1
- data/src/agent/Core/CoreMain.cpp +236 -349
- data/src/agent/Core/OptionParser.h +75 -89
- data/src/agent/Core/SecurityUpdateChecker.h +263 -100
- data/src/agent/Core/SpawningKit/Config.h +6 -2
- data/src/agent/Core/SpawningKit/Spawner.h +0 -45
- data/src/agent/Core/SpawningKit/UserSwitchingRules.h +1 -0
- data/src/agent/Shared/ApiAccountUtils.h +318 -0
- data/src/agent/Shared/ApiServerUtils.h +3 -104
- data/src/agent/Shared/Fundamentals/Initialization.cpp +81 -44
- data/src/agent/Shared/Fundamentals/Initialization.h +12 -7
- data/src/agent/TempDirToucher/TempDirToucherMain.cpp +21 -0
- data/src/agent/Watchdog/AgentWatcher.cpp +1 -1
- data/src/agent/Watchdog/ApiServer.h +100 -14
- data/src/agent/Watchdog/Config.h +340 -0
- data/src/agent/Watchdog/CoreWatcher.cpp +27 -13
- data/src/agent/Watchdog/InstanceDirToucher.cpp +1 -1
- data/src/agent/Watchdog/WatchdogMain.cpp +190 -206
- data/src/apache2_module/Bucket.cpp +4 -0
- data/src/apache2_module/Bucket.h +7 -3
- data/src/apache2_module/CBindings.cpp +49 -0
- data/src/apache2_module/Config.cpp +242 -0
- data/src/apache2_module/Config.h +109 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedDefinitions.cpp +485 -0
- data/src/apache2_module/{ConfigurationCommands.cpp.cxxcodebuilder → ConfigGeneral/AutoGeneratedDefinitions.cpp.cxxcodebuilder} +29 -15
- data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp +298 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.cpp.cxxcodebuilder +171 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp +854 -0
- data/src/apache2_module/ConfigGeneral/AutoGeneratedSetterFuncs.cpp.cxxcodebuilder +188 -0
- data/src/apache2_module/ConfigGeneral/ManifestGeneration.h +610 -0
- data/src/apache2_module/ConfigGeneral/SetterFuncs.h +65 -0
- data/src/apache2_module/DirConfig/AutoGeneratedCreateFunction.cpp +174 -0
- data/src/apache2_module/{MergeDirConfig.cpp.cxxcodebuilder → DirConfig/AutoGeneratedCreateFunction.cpp.cxxcodebuilder} +54 -32
- data/src/apache2_module/DirConfig/AutoGeneratedHeaderSerialization.cpp +113 -0
- data/src/apache2_module/{SetHeaders.cpp.cxxcodebuilder → DirConfig/AutoGeneratedHeaderSerialization.cpp.cxxcodebuilder} +34 -23
- data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp +426 -0
- data/src/apache2_module/DirConfig/AutoGeneratedManifestGeneration.cpp.cxxcodebuilder +165 -0
- data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp +269 -0
- data/src/apache2_module/DirConfig/AutoGeneratedMergeFunction.cpp.cxxcodebuilder +148 -0
- data/src/apache2_module/DirConfig/AutoGeneratedStruct.h +534 -0
- data/src/apache2_module/DirConfig/AutoGeneratedStruct.h.cxxcodebuilder +230 -0
- data/src/apache2_module/DirectoryMapper.h +19 -16
- data/src/apache2_module/Hooks.cpp +124 -138
- data/src/apache2_module/Hooks.h +9 -14
- data/src/apache2_module/ServerConfig/AutoGeneratedManifestGeneration.cpp +263 -0
- data/src/apache2_module/ServerConfig/AutoGeneratedManifestGeneration.cpp.cxxcodebuilder +152 -0
- data/src/apache2_module/ServerConfig/AutoGeneratedStruct.h +299 -0
- data/src/apache2_module/{ConfigurationFields.hpp.cxxcodebuilder → ServerConfig/AutoGeneratedStruct.h.cxxcodebuilder} +105 -18
- data/src/apache2_module/Utils.h +215 -0
- data/src/apache2_module/mod_passenger.c +16 -8
- data/src/cxx_supportlib/AppTypes.h +2 -0
- data/src/cxx_supportlib/ConfigKit/ConfigKit.h +1 -1
- data/src/cxx_supportlib/ConfigKit/DummyTranslator.h +8 -8
- data/src/cxx_supportlib/ConfigKit/IN_PRACTICE.md +7 -41
- data/src/cxx_supportlib/ConfigKit/PrefixTranslator.h +12 -66
- data/src/cxx_supportlib/ConfigKit/Schema.h +62 -11
- data/src/cxx_supportlib/ConfigKit/{ValidationUtils.h → SchemaUtils.h} +12 -3
- data/src/cxx_supportlib/ConfigKit/Store.h +17 -9
- data/src/cxx_supportlib/ConfigKit/SubComponentUtils.h +2 -1
- data/src/cxx_supportlib/ConfigKit/TableTranslator.h +13 -70
- data/src/cxx_supportlib/ConfigKit/Translator.h +125 -0
- data/src/cxx_supportlib/Constants.h +1 -3
- data/src/cxx_supportlib/FileTools/FileManip.cpp +297 -0
- data/src/cxx_supportlib/FileTools/FileManip.h +162 -0
- data/src/cxx_supportlib/{Utils → FileTools}/LargeFiles.cpp +6 -3
- data/src/cxx_supportlib/{Utils → FileTools}/LargeFiles.h +7 -5
- data/src/cxx_supportlib/FileTools/PathManip.cpp +240 -0
- data/src/cxx_supportlib/FileTools/PathManip.h +91 -0
- data/src/cxx_supportlib/FileTools/PathManipCBindings.cpp +62 -0
- data/src/{apache2_module/Configuration.h → cxx_supportlib/FileTools/PathManipCBindings.h} +12 -19
- data/src/cxx_supportlib/Hooks.h +19 -16
- data/src/cxx_supportlib/InstanceDirectory.h +11 -0
- data/src/cxx_supportlib/JsonTools/Autocast.h +79 -0
- data/src/cxx_supportlib/JsonTools/CBindings.cpp +364 -0
- data/src/cxx_supportlib/JsonTools/CBindings.h +101 -0
- data/src/cxx_supportlib/LoggingKit/Config.h +13 -0
- data/src/cxx_supportlib/LoggingKit/Context.h +5 -2
- data/src/cxx_supportlib/LoggingKit/Forward.h +0 -1
- data/src/cxx_supportlib/LoggingKit/Implementation.cpp +12 -4
- data/src/cxx_supportlib/ResourceLocator.h +15 -0
- data/src/cxx_supportlib/ServerKit/Config.h +156 -0
- data/src/cxx_supportlib/ServerKit/Context.h +59 -38
- data/src/cxx_supportlib/ServerKit/FileBufferedChannel.h +3 -2
- data/src/cxx_supportlib/ServerKit/HttpHeaderParser.h +2 -2
- data/src/cxx_supportlib/ServerKit/HttpServer.h +16 -2
- data/src/cxx_supportlib/ServerKit/Server.h +32 -15
- data/src/cxx_supportlib/Utils.cpp +0 -441
- data/src/cxx_supportlib/Utils.h +0 -158
- data/src/cxx_supportlib/Utils/Curl.h +1 -0
- data/src/cxx_supportlib/Utils/ProcessMetricsCollector.h +1 -0
- data/src/cxx_supportlib/Utils/StrIntUtilsNoStrictAliasing.cpp +2 -0
- data/src/cxx_supportlib/Utils/VariantMap.h +31 -0
- data/src/cxx_supportlib/WatchdogLauncher.cpp +7 -79
- data/src/cxx_supportlib/WatchdogLauncher.h +50 -53
- data/src/cxx_supportlib/WebSocketCommandReverseServer.h +981 -0
- data/src/cxx_supportlib/oxt/macros.hpp +9 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/COPYING +145 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/changelog.md +342 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/readme.md +49 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/base64/base64.hpp +178 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/client.hpp +33 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/close.hpp +342 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/asio.hpp +131 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/asio_ssl.hpp +39 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/chrono.hpp +68 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/connection_hdl.hpp +52 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/cpp11.hpp +162 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/functional.hpp +105 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/md5.hpp +448 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/memory.hpp +89 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/network.hpp +106 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/platforms.hpp +46 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/random.hpp +82 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/regex.hpp +59 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/stdint.hpp +73 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/system_error.hpp +84 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/thread.hpp +84 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/time.hpp +56 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/common/type_traits.hpp +65 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/concurrency/basic.hpp +46 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/concurrency/none.hpp +80 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/asio.hpp +77 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/asio_client.hpp +77 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/asio_no_tls.hpp +73 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/asio_no_tls_client.hpp +73 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/boost_config.hpp +72 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/core.hpp +285 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/core_client.hpp +294 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/debug.hpp +286 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/debug_asio.hpp +77 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/debug_asio_no_tls.hpp +73 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/minimal_client.hpp +72 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/config/minimal_server.hpp +312 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/connection.hpp +1651 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/connection_base.hpp +38 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/endpoint.hpp +700 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/endpoint_base.hpp +38 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/error.hpp +277 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/extensions/extension.hpp +102 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/extensions/permessage_deflate/disabled.hpp +128 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp +752 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/frame.hpp +861 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/constants.hpp +308 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/impl/parser.hpp +196 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/impl/request.hpp +191 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/impl/response.hpp +266 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/parser.hpp +619 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/request.hpp +124 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/http/response.hpp +188 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/impl/connection_impl.hpp +2372 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/impl/endpoint_impl.hpp +269 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/impl/utilities_impl.hpp +87 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/logger/basic.hpp +199 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/logger/levels.hpp +203 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/logger/stub.hpp +119 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/logger/syslog.hpp +146 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/message_buffer/alloc.hpp +105 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/message_buffer/message.hpp +340 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/message_buffer/pool.hpp +229 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/processors/base.hpp +299 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/processors/hybi00.hpp +462 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/processors/hybi07.hpp +78 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/processors/hybi08.hpp +83 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/processors/hybi13.hpp +1056 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/processors/processor.hpp +407 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/random/none.hpp +60 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/random/random_device.hpp +80 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/roles/client_endpoint.hpp +173 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/roles/server_endpoint.hpp +190 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/server.hpp +33 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/sha1/sha1.hpp +189 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/asio/base.hpp +232 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/asio/connection.hpp +1204 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/asio/endpoint.hpp +1147 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/asio/security/base.hpp +159 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/asio/security/none.hpp +370 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/asio/security/tls.hpp +484 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/base/connection.hpp +238 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/base/endpoint.hpp +77 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/debug/base.hpp +104 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/debug/connection.hpp +412 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/debug/endpoint.hpp +140 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/iostream/base.hpp +133 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/iostream/connection.hpp +714 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/iostream/endpoint.hpp +222 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/stub/base.hpp +95 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/stub/connection.hpp +286 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/transport/stub/endpoint.hpp +140 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/uri.hpp +355 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/utf8_validator.hpp +154 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/utilities.hpp +182 -0
- data/src/cxx_supportlib/vendor-copy/websocketpp/websocketpp/version.hpp +61 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio.hpp +121 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/async_result.hpp +96 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_datagram_socket.hpp +951 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_deadline_timer.hpp +520 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_io_object.hpp +258 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_raw_socket.hpp +942 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_seq_packet_socket.hpp +567 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_serial_port.hpp +697 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_signal_set.hpp +386 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket.hpp +1519 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_acceptor.hpp +1137 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_iostream.hpp +288 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_streambuf.hpp +569 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_stream_socket.hpp +854 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_streambuf.hpp +371 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_streambuf_fwd.hpp +35 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/basic_waitable_timer.hpp +521 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffer.hpp +2241 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_read_stream.hpp +246 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_read_stream_fwd.hpp +27 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_stream.hpp +260 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_stream_fwd.hpp +27 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_write_stream.hpp +238 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_write_stream_fwd.hpp +27 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/buffers_iterator.hpp +483 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/completion_condition.hpp +220 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/connect.hpp +825 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/coroutine.hpp +330 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/datagram_socket_service.hpp +438 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/deadline_timer.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/deadline_timer_service.hpp +173 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/addressof.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/array.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/array_fwd.hpp +34 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/assert.hpp +32 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/atomic_count.hpp +47 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/base_from_completion_cond.hpp +70 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/bind_handler.hpp +491 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/buffer_resize_guard.hpp +68 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/buffer_sequence_adapter.hpp +385 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/buffered_stream_storage.hpp +128 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/call_stack.hpp +127 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/chrono_time_traits.hpp +192 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/completion_handler.hpp +83 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/config.hpp +1050 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/consuming_buffers.hpp +294 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/cstdint.hpp +48 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/date_time_fwd.hpp +34 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/deadline_timer_service.hpp +229 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/dependent_type.hpp +38 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/descriptor_ops.hpp +119 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/descriptor_read_op.hpp +121 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/descriptor_write_op.hpp +121 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/dev_poll_reactor.hpp +208 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/epoll_reactor.hpp +244 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/event.hpp +50 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/eventfd_select_interrupter.hpp +85 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/fd_set_adapter.hpp +41 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/fenced_block.hpp +82 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/function.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_arm_fenced_block.hpp +91 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_hppa_fenced_block.hpp +68 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_sync_fenced_block.hpp +65 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_x86_fenced_block.hpp +99 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_alloc_helpers.hpp +82 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_cont_helpers.hpp +45 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_invoke_helpers.hpp +57 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_tracking.hpp +161 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_type_requirements.hpp +480 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/hash_map.hpp +333 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/buffer_sequence_adapter.ipp +120 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/descriptor_ops.ipp +453 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/dev_poll_reactor.hpp +80 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/dev_poll_reactor.ipp +432 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/epoll_reactor.hpp +78 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/epoll_reactor.ipp +688 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/eventfd_select_interrupter.ipp +167 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/handler_tracking.ipp +307 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/kqueue_reactor.hpp +82 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/kqueue_reactor.ipp +498 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/pipe_select_interrupter.ipp +126 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_event.ipp +49 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_mutex.ipp +48 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_thread.ipp +76 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_tss_ptr.ipp +48 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/reactive_descriptor_service.ipp +210 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/reactive_serial_port_service.ipp +153 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/reactive_socket_service_base.ipp +269 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/resolver_service_base.ipp +132 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/select_reactor.hpp +89 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/select_reactor.ipp +315 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/service_registry.hpp +90 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/service_registry.ipp +190 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/signal_set_service.ipp +649 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/socket_ops.ipp +3470 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/socket_select_interrupter.ipp +178 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_service.hpp +120 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_service.ipp +178 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/task_io_service.hpp +80 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/task_io_service.ipp +476 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/throw_error.ipp +47 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/timer_queue_ptime.ipp +86 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/timer_queue_set.ipp +103 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_control.hpp +136 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/keyword_tss_ptr.hpp +72 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/kqueue_reactor.hpp +222 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/limits.hpp +26 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/local_free_on_block_exit.hpp +61 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/macos_fenced_block.hpp +63 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/memory.hpp +31 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/mutex.hpp +50 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/noncopyable.hpp +45 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_event.hpp +90 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_fenced_block.hpp +47 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_mutex.hpp +66 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_reactor.hpp +69 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_signal_blocker.hpp +71 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_socket_service.hpp +500 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_static_mutex.hpp +62 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_thread.hpp +63 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_tss_ptr.hpp +70 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/object_pool.hpp +148 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/old_win_sdk_compat.hpp +216 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/op_queue.hpp +158 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/operation.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/pipe_select_interrupter.hpp +91 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/pop_options.hpp +131 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_event.hpp +128 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_fd_set_adapter.hpp +120 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_mutex.hpp +78 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_signal_blocker.hpp +87 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_static_mutex.hpp +66 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_thread.hpp +107 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_tss_ptr.hpp +81 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/push_options.hpp +166 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_descriptor_service.hpp +324 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_null_buffers_op.hpp +90 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_serial_port_service.hpp +236 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_accept_op.hpp +138 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_connect_op.hpp +108 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_recv_op.hpp +125 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_recvfrom_op.hpp +135 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_recvmsg_op.hpp +127 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_send_op.hpp +122 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_sendto_op.hpp +125 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_service.hpp +460 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_service_base.hpp +452 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor.hpp +32 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor_fwd.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor_op.hpp +63 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor_op_queue.hpp +170 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/regex_fwd.hpp +35 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolve_endpoint_op.hpp +123 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolve_op.hpp +133 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolver_service.hpp +131 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolver_service_base.hpp +131 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scoped_lock.hpp +103 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scoped_ptr.hpp +81 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/select_interrupter.hpp +48 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/select_reactor.hpp +221 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/service_registry.hpp +146 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/shared_ptr.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_blocker.hpp +46 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_handler.hpp +84 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_init.hpp +49 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_op.hpp +51 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_set_service.hpp +218 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_holder.hpp +100 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_ops.hpp +336 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_option.hpp +318 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_select_interrupter.hpp +93 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_types.hpp +410 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/solaris_fenced_block.hpp +63 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/static_mutex.hpp +54 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_event.hpp +178 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_fenced_block.hpp +64 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_mutex.hpp +75 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_static_mutex.hpp +83 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_thread.hpp +67 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/strand_service.hpp +144 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/task_io_service.hpp +203 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/task_io_service_operation.hpp +78 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/task_io_service_thread_info.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/thread.hpp +58 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/thread_info_base.hpp +93 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/throw_error.hpp +55 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/throw_exception.hpp +53 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue.hpp +333 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue_base.hpp +70 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue_ptime.hpp +95 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue_set.hpp +68 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_scheduler.hpp +35 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_scheduler_fwd.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/tss_ptr.hpp +71 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/type_traits.hpp +60 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/variadic_templates.hpp +63 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/wait_handler.hpp +85 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/wait_op.hpp +47 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/weak_ptr.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/win_iocp_serial_port_service.hpp +230 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/winsock_init.hpp +130 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/detail/wrapped_handler.hpp +293 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/error.hpp +345 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/basic_endpoint.hpp +195 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/datagram_protocol.hpp +125 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/detail/endpoint.hpp +135 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/detail/impl/endpoint.ipp +111 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/raw_protocol.hpp +123 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/seq_packet_protocol.hpp +124 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/generic/stream_protocol.hpp +129 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/handler_alloc_hook.hpp +83 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/handler_continuation_hook.hpp +56 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/handler_invoke_hook.hpp +87 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/handler_type.hpp +114 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/high_resolution_timer.hpp +65 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/buffered_read_stream.hpp +360 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/buffered_write_stream.hpp +340 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/connect.hpp +432 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/error.ipp +130 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/handler_alloc_hook.ipp +79 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/io_service.hpp +156 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/io_service.ipp +157 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read.hpp +755 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read_at.hpp +812 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read_until.hpp +1149 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/serial_port_base.hpp +61 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/serial_port_base.ipp +556 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/spawn.hpp +355 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/src.cpp +25 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/src.hpp +73 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/use_future.hpp +179 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/write.hpp +767 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/impl/write_at.hpp +827 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/io_service.hpp +772 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address.hpp +202 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v4.hpp +243 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v6.hpp +248 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_endpoint.hpp +265 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver.hpp +270 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_entry.hpp +96 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_iterator.hpp +262 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_query.hpp +246 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/detail/endpoint.hpp +141 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/detail/impl/endpoint.ipp +206 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/detail/socket_option.hpp +571 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/host_name.hpp +44 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/icmp.hpp +117 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address.hpp +55 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address.ipp +228 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v4.hpp +55 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v4.ipp +180 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v6.hpp +55 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v6.ipp +300 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/basic_endpoint.hpp +57 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/host_name.ipp +56 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/multicast.hpp +193 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/resolver_query_base.hpp +132 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/resolver_service.hpp +178 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/tcp.hpp +157 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/udp.hpp +113 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/unicast.hpp +72 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ip/v6_only.hpp +71 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/is_read_buffered.hpp +61 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/is_write_buffered.hpp +61 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/local/basic_endpoint.hpp +241 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/local/connect_pair.hpp +106 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/local/datagram_protocol.hpp +82 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/local/detail/endpoint.hpp +135 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/local/detail/impl/endpoint.ipp +130 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/local/stream_protocol.hpp +92 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/placeholders.hpp +125 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/posix/basic_descriptor.hpp +492 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/posix/basic_stream_descriptor.hpp +364 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/posix/descriptor_base.hpp +99 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/posix/stream_descriptor.hpp +39 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/posix/stream_descriptor_service.hpp +262 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/raw_socket_service.hpp +438 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/read.hpp +633 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/read_at.hpp +666 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/read_until.hpp +925 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/seq_packet_socket_service.hpp +386 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/serial_port.hpp +38 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/serial_port_base.hpp +169 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/serial_port_service.hpp +255 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/signal_set.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/signal_set_service.hpp +136 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/socket_acceptor_service.hpp +308 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/socket_base.hpp +522 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/spawn.hpp +267 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/basic_context.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/context.hpp +789 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/context_base.hpp +194 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/context_service.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/buffered_handshake_op.hpp +112 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/engine.hpp +166 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/handshake_op.hpp +70 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/impl/engine.ipp +327 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/impl/openssl_init.ipp +166 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/io.hpp +351 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/openssl_init.hpp +103 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/openssl_types.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/password_callback.hpp +74 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/read_op.hpp +75 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/shutdown_op.hpp +62 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/stream_core.hpp +128 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/verify_callback.hpp +70 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/write_op.hpp +75 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/error.hpp +115 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/context.hpp +73 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/context.ipp +1177 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/error.ipp +102 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/rfc2818_verification.ipp +168 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/src.hpp +28 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/basic_context.hpp +436 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/context_service.hpp +176 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/detail/openssl_context_service.hpp +396 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/detail/openssl_operation.hpp +526 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/detail/openssl_stream_service.hpp +573 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/stream.hpp +503 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/old/stream_service.hpp +186 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/rfc2818_verification.hpp +102 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/stream.hpp +758 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/stream_base.hpp +54 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/stream_service.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/verify_context.hpp +75 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/verify_mode.hpp +65 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/steady_timer.hpp +63 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/strand.hpp +254 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/stream_socket_service.hpp +382 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/streambuf.hpp +35 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/system_timer.hpp +59 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/time_traits.hpp +88 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/unyield.hpp +21 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/use_future.hpp +94 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/version.hpp +23 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/wait_traits.hpp +43 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/waitable_timer_service.hpp +170 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_handle.hpp +283 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_object_handle.hpp +180 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_random_access_handle.hpp +378 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_stream_handle.hpp +361 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/object_handle.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/object_handle_service.hpp +179 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/overlapped_ptr.hpp +118 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/random_access_handle.hpp +39 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/random_access_handle_service.hpp +222 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/stream_handle.hpp +39 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/windows/stream_handle_service.hpp +220 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/write.hpp +620 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/write_at.hpp +672 -0
- data/src/cxx_supportlib/vendor-modified/boost/asio/yield.hpp +23 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono.hpp +20 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/chrono.hpp +15 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/chrono_io.hpp +34 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/chrono.hpp +46 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/mac/chrono.hpp +242 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp +356 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/mac/thread_clock.hpp +92 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/posix/chrono.hpp +121 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp +354 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/posix/thread_clock.hpp +92 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/process_cpu_clocks.hpp +46 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/thread_clock.hpp +46 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp +54 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/scan_keyword.hpp +163 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/floor.hpp +36 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/include.hpp +23 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_get.hpp +593 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_io.hpp +295 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_put.hpp +317 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_style.hpp +35 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_units.hpp +1003 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/ios_base_state.hpp +152 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/time_point_get.hpp +330 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/time_point_io.hpp +1243 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/time_point_put.hpp +261 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/time_point_units.hpp +260 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/timezone.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/utility/ios_base_state_ptr.hpp +437 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/utility/manip_base.hpp +101 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io/utility/to_string.hpp +50 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/io_v1/chrono_io.hpp +637 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/process_cpu_clocks.hpp +525 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/round.hpp +59 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/thread_clock.hpp +75 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/typeof/boost/chrono/chrono.hpp +32 -0
- data/src/cxx_supportlib/vendor-modified/boost/chrono/typeof/boost/ratio.hpp +24 -0
- data/src/cxx_supportlib/vendor-modified/boost/detail/atomic_count.hpp +21 -0
- data/src/cxx_supportlib/vendor-modified/boost/integer/common_factor.hpp +16 -0
- data/src/cxx_supportlib/vendor-modified/boost/integer/common_factor_rt.hpp +460 -0
- data/src/cxx_supportlib/vendor-modified/boost/integer/integer_log2.hpp +112 -0
- data/src/cxx_supportlib/vendor-modified/boost/integer/integer_mask.hpp +126 -0
- data/src/cxx_supportlib/vendor-modified/boost/integer/static_min_max.hpp +51 -0
- data/src/cxx_supportlib/vendor-modified/boost/libs/chrono/src/chrono.cpp +15 -0
- data/src/cxx_supportlib/vendor-modified/boost/libs/chrono/src/process_cpu_clocks.cpp +18 -0
- data/src/cxx_supportlib/vendor-modified/boost/libs/chrono/src/thread_clock.cpp +19 -0
- data/src/cxx_supportlib/vendor-modified/boost/libs/random/src/random_device.cpp +250 -0
- data/src/cxx_supportlib/vendor-modified/boost/pointer_cast.hpp +121 -0
- data/src/cxx_supportlib/vendor-modified/boost/random.hpp +91 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/additive_combine.hpp +283 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/bernoulli_distribution.hpp +197 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/beta_distribution.hpp +184 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/binomial_distribution.hpp +434 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/cauchy_distribution.hpp +214 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/chi_squared_distribution.hpp +209 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/auto_link.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/config.hpp +18 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/const_mod.hpp +216 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/disable_warnings.hpp +29 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/enable_warnings.hpp +22 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/generator_bits.hpp +36 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/generator_seed_seq.hpp +40 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/int_float_pair.hpp +121 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/integer_log2.hpp +84 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/iterator_mixin.hpp +45 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/large_arithmetic.hpp +122 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/operators.hpp +84 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/polynomial.hpp +384 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/ptr_helper.hpp +67 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/seed.hpp +115 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/seed_impl.hpp +398 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/signed_unsigned_tools.hpp +89 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/uniform_int_float.hpp +76 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/detail/vector_io.hpp +75 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/discard_block.hpp +241 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/discrete_distribution.hpp +636 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/exponential_distribution.hpp +386 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/extreme_value_distribution.hpp +177 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/fisher_f_distribution.hpp +183 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/gamma_distribution.hpp +292 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/generate_canonical.hpp +96 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/geometric_distribution.hpp +267 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/hyperexponential_distribution.hpp +883 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/independent_bits.hpp +271 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/inversive_congruential.hpp +267 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/lagged_fibonacci.hpp +537 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/laplace_distribution.hpp +175 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/linear_congruential.hpp +466 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/linear_feedback_shift.hpp +217 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/lognormal_distribution.hpp +254 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/mersenne_twister.hpp +682 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/negative_binomial_distribution.hpp +220 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/non_central_chi_squared_distribution.hpp +221 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/normal_distribution.hpp +374 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/piecewise_constant_distribution.hpp +466 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/piecewise_linear_distribution.hpp +531 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/poisson_distribution.hpp +360 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/random_device.hpp +143 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/random_number_generator.hpp +73 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/ranlux.hpp +99 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/seed_seq.hpp +118 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/shuffle_order.hpp +269 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/shuffle_output.hpp +51 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/student_t_distribution.hpp +180 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/subtract_with_carry.hpp +613 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/taus88.hpp +45 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/traits.hpp +107 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/triangle_distribution.hpp +232 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_01.hpp +257 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_int.hpp +99 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_int_distribution.hpp +419 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_on_sphere.hpp +284 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_real.hpp +82 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_real_distribution.hpp +241 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_smallint.hpp +307 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/variate_generator.hpp +122 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/weibull_distribution.hpp +177 -0
- data/src/cxx_supportlib/vendor-modified/boost/random/xor_combine.hpp +208 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio.hpp +14 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/detail/ratio_io.hpp +1342 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/include.hpp +16 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/abs.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/arithmetic.hpp +22 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/comparison.hpp +19 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/divides.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/equal_to.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/gcd.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/greater.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/greater_equal.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/lcm.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/less.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/less_equal.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/minus.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/negate.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/not_equal_to.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/numeric_cast.hpp +31 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/plus.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/rational_c_tag.hpp +25 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/rational_constant.hpp +15 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/sign.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/mpl/times.hpp +30 -0
- data/src/cxx_supportlib/vendor-modified/boost/ratio/ratio_io.hpp +1076 -0
- data/src/cxx_supportlib/vendor-modified/boost/rational.hpp +1002 -0
- data/src/cxx_supportlib/vendor-modified/modp_b64.cpp +11 -0
- data/src/helper-scripts/rack-preloader.rb +1 -1
- data/src/nginx_module/{ConfigurationCommands.c → ConfigGeneral/AutoGeneratedDefinitions.c} +351 -134
- data/src/nginx_module/{ConfigurationCommands.c.cxxcodebuilder → ConfigGeneral/AutoGeneratedDefinitions.c.cxxcodebuilder} +14 -25
- data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c +396 -0
- data/src/nginx_module/ConfigGeneral/AutoGeneratedManifestDefaultsInitialization.c.cxxcodebuilder +160 -0
- data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c +831 -0
- data/src/nginx_module/ConfigGeneral/AutoGeneratedSetterFuncs.c.cxxcodebuilder +168 -0
- data/src/nginx_module/ConfigGeneral/ManifestGeneration.c +887 -0
- data/src/nginx_module/ConfigGeneral/ManifestGeneration.h +100 -0
- data/src/nginx_module/Configuration.c +165 -621
- data/src/nginx_module/Configuration.h +43 -33
- data/src/nginx_module/ContentHandler.c +46 -40
- data/src/nginx_module/LocationConfig/AutoGeneratedCreateFunction.c +282 -0
- data/src/nginx_module/{CreateLocationConfig.c.cxxcodebuilder → LocationConfig/AutoGeneratedCreateFunction.c.cxxcodebuilder} +43 -17
- data/src/nginx_module/{CacheLocationConfig.c → LocationConfig/AutoGeneratedHeaderSerialization.c} +148 -180
- data/src/nginx_module/{CacheLocationConfig.c.cxxcodebuilder → LocationConfig/AutoGeneratedHeaderSerialization.c.cxxcodebuilder} +13 -11
- data/src/nginx_module/LocationConfig/AutoGeneratedManifestGeneration.c +595 -0
- data/src/nginx_module/LocationConfig/AutoGeneratedManifestGeneration.c.cxxcodebuilder +190 -0
- data/src/nginx_module/{MergeLocationConfig.c → LocationConfig/AutoGeneratedMergeFunction.c} +32 -42
- data/src/nginx_module/{MergeLocationConfig.c.cxxcodebuilder → LocationConfig/AutoGeneratedMergeFunction.c.cxxcodebuilder} +18 -11
- data/src/nginx_module/LocationConfig/AutoGeneratedStruct.h +220 -0
- data/src/nginx_module/{LocationConfig.h.cxxcodebuilder → LocationConfig/AutoGeneratedStruct.h.cxxcodebuilder} +70 -48
- data/src/nginx_module/MainConfig/AutoGeneratedCreateFunction.c +163 -0
- data/src/nginx_module/MainConfig/AutoGeneratedCreateFunction.c.cxxcodebuilder +125 -0
- data/src/nginx_module/MainConfig/AutoGeneratedManifestGeneration.c +303 -0
- data/src/nginx_module/MainConfig/AutoGeneratedManifestGeneration.c.cxxcodebuilder +173 -0
- data/src/nginx_module/MainConfig/AutoGeneratedStruct.h +133 -0
- data/src/nginx_module/MainConfig/AutoGeneratedStruct.h.cxxcodebuilder +154 -0
- data/src/nginx_module/config +13 -4
- data/src/nginx_module/ngx_http_passenger_module.c +154 -84
- data/src/ruby_supportlib/phusion_passenger.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +613 -131
- data/src/ruby_supportlib/phusion_passenger/apache2/config_utils.rb +52 -0
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +18 -4
- data/src/ruby_supportlib/phusion_passenger/config/main.rb +2 -0
- data/src/ruby_supportlib/phusion_passenger/config/system_properties_command.rb +104 -0
- data/src/ruby_supportlib/phusion_passenger/constants.rb +0 -2
- data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +470 -138
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
- data/src/ruby_supportlib/phusion_passenger/platform_info.rb +17 -0
- data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +11 -1
- data/src/ruby_supportlib/phusion_passenger/platform_info/compiler.rb +7 -7
- data/src/ruby_supportlib/phusion_passenger/platform_info/networking.rb +293 -0
- data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +8 -54
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +1 -5
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +4 -7
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller.rb +1 -1
- data/src/schema_printer/SchemaPrinterMain.cpp +78 -0
- data/src/schema_printer/SchemaPrinterMain.cpp.cxxcodebuilder +116 -0
- metadata +671 -30
- data/src/apache2_module/Configuration.cpp +0 -737
- data/src/apache2_module/Configuration.hpp +0 -274
- data/src/apache2_module/ConfigurationCommands.cpp +0 -199
- data/src/apache2_module/ConfigurationFields.hpp +0 -187
- data/src/apache2_module/ConfigurationSetters.cpp +0 -436
- data/src/apache2_module/ConfigurationSetters.cpp.cxxcodebuilder +0 -144
- data/src/apache2_module/CreateDirConfig.cpp +0 -68
- data/src/apache2_module/CreateDirConfig.cpp.cxxcodebuilder +0 -81
- data/src/apache2_module/MergeDirConfig.cpp +0 -155
- data/src/apache2_module/SetHeaders.cpp +0 -111
- data/src/nginx_module/CreateLocationConfig.c +0 -100
- data/src/nginx_module/LocationConfig.h +0 -95
@@ -0,0 +1,3470 @@
|
|
1
|
+
//
|
2
|
+
// detail/impl/socket_ops.ipp
|
3
|
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
4
|
+
//
|
5
|
+
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
6
|
+
//
|
7
|
+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
8
|
+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
9
|
+
//
|
10
|
+
|
11
|
+
#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
|
12
|
+
#define BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
|
13
|
+
|
14
|
+
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
15
|
+
# pragma once
|
16
|
+
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
17
|
+
|
18
|
+
#include <boost/asio/detail/config.hpp>
|
19
|
+
|
20
|
+
#include <cctype>
|
21
|
+
#include <cstdio>
|
22
|
+
#include <cstdlib>
|
23
|
+
#include <cstring>
|
24
|
+
#include <cerrno>
|
25
|
+
#include <new>
|
26
|
+
#include <boost/asio/detail/assert.hpp>
|
27
|
+
#include <boost/asio/detail/socket_ops.hpp>
|
28
|
+
#include <boost/asio/error.hpp>
|
29
|
+
|
30
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
31
|
+
# include <codecvt>
|
32
|
+
# include <locale>
|
33
|
+
# include <string>
|
34
|
+
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
35
|
+
|
36
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) \
|
37
|
+
|| defined(__MACH__) && defined(__APPLE__)
|
38
|
+
# if defined(BOOST_ASIO_HAS_PTHREADS)
|
39
|
+
# include <pthread.h>
|
40
|
+
# endif // defined(BOOST_ASIO_HAS_PTHREADS)
|
41
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
42
|
+
// || defined(__MACH__) && defined(__APPLE__)
|
43
|
+
|
44
|
+
#include <boost/asio/detail/push_options.hpp>
|
45
|
+
|
46
|
+
namespace boost {
|
47
|
+
namespace asio {
|
48
|
+
namespace detail {
|
49
|
+
namespace socket_ops {
|
50
|
+
|
51
|
+
#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
52
|
+
|
53
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
54
|
+
struct msghdr { int msg_namelen; };
|
55
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
56
|
+
|
57
|
+
#if defined(__hpux)
|
58
|
+
// HP-UX doesn't declare these functions extern "C", so they are declared again
|
59
|
+
// here to avoid linker errors about undefined symbols.
|
60
|
+
extern "C" char* if_indextoname(unsigned int, char*);
|
61
|
+
extern "C" unsigned int if_nametoindex(const char*);
|
62
|
+
#endif // defined(__hpux)
|
63
|
+
|
64
|
+
#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
65
|
+
|
66
|
+
inline void clear_last_error()
|
67
|
+
{
|
68
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
69
|
+
WSASetLastError(0);
|
70
|
+
#else
|
71
|
+
errno = 0;
|
72
|
+
#endif
|
73
|
+
}
|
74
|
+
|
75
|
+
#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
76
|
+
|
77
|
+
template <typename ReturnType>
|
78
|
+
inline ReturnType error_wrapper(ReturnType return_value,
|
79
|
+
boost::system::error_code& ec)
|
80
|
+
{
|
81
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
82
|
+
ec = boost::system::error_code(WSAGetLastError(),
|
83
|
+
boost::asio::error::get_system_category());
|
84
|
+
#else
|
85
|
+
ec = boost::system::error_code(errno,
|
86
|
+
boost::asio::error::get_system_category());
|
87
|
+
#endif
|
88
|
+
return return_value;
|
89
|
+
}
|
90
|
+
|
91
|
+
template <typename SockLenType>
|
92
|
+
inline socket_type call_accept(SockLenType msghdr::*,
|
93
|
+
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
|
94
|
+
{
|
95
|
+
SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
|
96
|
+
socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
|
97
|
+
if (addrlen)
|
98
|
+
*addrlen = (std::size_t)tmp_addrlen;
|
99
|
+
return result;
|
100
|
+
}
|
101
|
+
|
102
|
+
socket_type accept(socket_type s, socket_addr_type* addr,
|
103
|
+
std::size_t* addrlen, boost::system::error_code& ec)
|
104
|
+
{
|
105
|
+
if (s == invalid_socket)
|
106
|
+
{
|
107
|
+
ec = boost::asio::error::bad_descriptor;
|
108
|
+
return invalid_socket;
|
109
|
+
}
|
110
|
+
|
111
|
+
clear_last_error();
|
112
|
+
|
113
|
+
socket_type new_s = error_wrapper(call_accept(
|
114
|
+
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
115
|
+
if (new_s == invalid_socket)
|
116
|
+
return new_s;
|
117
|
+
|
118
|
+
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
119
|
+
int optval = 1;
|
120
|
+
int result = error_wrapper(::setsockopt(new_s,
|
121
|
+
SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
|
122
|
+
if (result != 0)
|
123
|
+
{
|
124
|
+
::close(new_s);
|
125
|
+
return invalid_socket;
|
126
|
+
}
|
127
|
+
#endif
|
128
|
+
|
129
|
+
ec = boost::system::error_code();
|
130
|
+
return new_s;
|
131
|
+
}
|
132
|
+
|
133
|
+
socket_type sync_accept(socket_type s, state_type state,
|
134
|
+
socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec)
|
135
|
+
{
|
136
|
+
// Accept a socket.
|
137
|
+
for (;;)
|
138
|
+
{
|
139
|
+
// Try to complete the operation without blocking.
|
140
|
+
socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec);
|
141
|
+
|
142
|
+
// Check if operation succeeded.
|
143
|
+
if (new_socket != invalid_socket)
|
144
|
+
return new_socket;
|
145
|
+
|
146
|
+
// Operation failed.
|
147
|
+
if (ec == boost::asio::error::would_block
|
148
|
+
|| ec == boost::asio::error::try_again)
|
149
|
+
{
|
150
|
+
if (state & user_set_non_blocking)
|
151
|
+
return invalid_socket;
|
152
|
+
// Fall through to retry operation.
|
153
|
+
}
|
154
|
+
else if (ec == boost::asio::error::connection_aborted)
|
155
|
+
{
|
156
|
+
if (state & enable_connection_aborted)
|
157
|
+
return invalid_socket;
|
158
|
+
// Fall through to retry operation.
|
159
|
+
}
|
160
|
+
#if defined(EPROTO)
|
161
|
+
else if (ec.value() == EPROTO)
|
162
|
+
{
|
163
|
+
if (state & enable_connection_aborted)
|
164
|
+
return invalid_socket;
|
165
|
+
// Fall through to retry operation.
|
166
|
+
}
|
167
|
+
#endif // defined(EPROTO)
|
168
|
+
else
|
169
|
+
return invalid_socket;
|
170
|
+
|
171
|
+
// Wait for socket to become ready.
|
172
|
+
if (socket_ops::poll_read(s, 0, ec) < 0)
|
173
|
+
return invalid_socket;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
#if defined(BOOST_ASIO_HAS_IOCP)
|
178
|
+
|
179
|
+
void complete_iocp_accept(socket_type s,
|
180
|
+
void* output_buffer, DWORD address_length,
|
181
|
+
socket_addr_type* addr, std::size_t* addrlen,
|
182
|
+
socket_type new_socket, boost::system::error_code& ec)
|
183
|
+
{
|
184
|
+
// Map non-portable errors to their portable counterparts.
|
185
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
186
|
+
ec = boost::asio::error::connection_aborted;
|
187
|
+
|
188
|
+
if (!ec)
|
189
|
+
{
|
190
|
+
// Get the address of the peer.
|
191
|
+
if (addr && addrlen)
|
192
|
+
{
|
193
|
+
LPSOCKADDR local_addr = 0;
|
194
|
+
int local_addr_length = 0;
|
195
|
+
LPSOCKADDR remote_addr = 0;
|
196
|
+
int remote_addr_length = 0;
|
197
|
+
GetAcceptExSockaddrs(output_buffer, 0, address_length,
|
198
|
+
address_length, &local_addr, &local_addr_length,
|
199
|
+
&remote_addr, &remote_addr_length);
|
200
|
+
if (static_cast<std::size_t>(remote_addr_length) > *addrlen)
|
201
|
+
{
|
202
|
+
ec = boost::asio::error::invalid_argument;
|
203
|
+
}
|
204
|
+
else
|
205
|
+
{
|
206
|
+
using namespace std; // For memcpy.
|
207
|
+
memcpy(addr, remote_addr, remote_addr_length);
|
208
|
+
*addrlen = static_cast<std::size_t>(remote_addr_length);
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
// Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname
|
213
|
+
// and getpeername will work on the accepted socket.
|
214
|
+
SOCKET update_ctx_param = s;
|
215
|
+
socket_ops::state_type state = 0;
|
216
|
+
socket_ops::setsockopt(new_socket, state,
|
217
|
+
SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
|
218
|
+
&update_ctx_param, sizeof(SOCKET), ec);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
222
|
+
#else // defined(BOOST_ASIO_HAS_IOCP)
|
223
|
+
|
224
|
+
bool non_blocking_accept(socket_type s,
|
225
|
+
state_type state, socket_addr_type* addr, std::size_t* addrlen,
|
226
|
+
boost::system::error_code& ec, socket_type& new_socket)
|
227
|
+
{
|
228
|
+
for (;;)
|
229
|
+
{
|
230
|
+
// Accept the waiting connection.
|
231
|
+
new_socket = socket_ops::accept(s, addr, addrlen, ec);
|
232
|
+
|
233
|
+
// Check if operation succeeded.
|
234
|
+
if (new_socket != invalid_socket)
|
235
|
+
return true;
|
236
|
+
|
237
|
+
// Retry operation if interrupted by signal.
|
238
|
+
if (ec == boost::asio::error::interrupted)
|
239
|
+
continue;
|
240
|
+
|
241
|
+
// Operation failed.
|
242
|
+
if (ec == boost::asio::error::would_block
|
243
|
+
|| ec == boost::asio::error::try_again)
|
244
|
+
{
|
245
|
+
if (state & user_set_non_blocking)
|
246
|
+
return true;
|
247
|
+
// Fall through to retry operation.
|
248
|
+
}
|
249
|
+
else if (ec == boost::asio::error::connection_aborted)
|
250
|
+
{
|
251
|
+
if (state & enable_connection_aborted)
|
252
|
+
return true;
|
253
|
+
// Fall through to retry operation.
|
254
|
+
}
|
255
|
+
#if defined(EPROTO)
|
256
|
+
else if (ec.value() == EPROTO)
|
257
|
+
{
|
258
|
+
if (state & enable_connection_aborted)
|
259
|
+
return true;
|
260
|
+
// Fall through to retry operation.
|
261
|
+
}
|
262
|
+
#endif // defined(EPROTO)
|
263
|
+
else
|
264
|
+
return true;
|
265
|
+
|
266
|
+
return false;
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
271
|
+
|
272
|
+
template <typename SockLenType>
|
273
|
+
inline int call_bind(SockLenType msghdr::*,
|
274
|
+
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
|
275
|
+
{
|
276
|
+
return ::bind(s, addr, (SockLenType)addrlen);
|
277
|
+
}
|
278
|
+
|
279
|
+
int bind(socket_type s, const socket_addr_type* addr,
|
280
|
+
std::size_t addrlen, boost::system::error_code& ec)
|
281
|
+
{
|
282
|
+
if (s == invalid_socket)
|
283
|
+
{
|
284
|
+
ec = boost::asio::error::bad_descriptor;
|
285
|
+
return socket_error_retval;
|
286
|
+
}
|
287
|
+
|
288
|
+
clear_last_error();
|
289
|
+
int result = error_wrapper(call_bind(
|
290
|
+
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
291
|
+
if (result == 0)
|
292
|
+
ec = boost::system::error_code();
|
293
|
+
return result;
|
294
|
+
}
|
295
|
+
|
296
|
+
int close(socket_type s, state_type& state,
|
297
|
+
bool destruction, boost::system::error_code& ec)
|
298
|
+
{
|
299
|
+
int result = 0;
|
300
|
+
if (s != invalid_socket)
|
301
|
+
{
|
302
|
+
// We don't want the destructor to block, so set the socket to linger in
|
303
|
+
// the background. If the user doesn't like this behaviour then they need
|
304
|
+
// to explicitly close the socket.
|
305
|
+
if (destruction && (state & user_set_linger))
|
306
|
+
{
|
307
|
+
::linger opt;
|
308
|
+
opt.l_onoff = 0;
|
309
|
+
opt.l_linger = 0;
|
310
|
+
boost::system::error_code ignored_ec;
|
311
|
+
socket_ops::setsockopt(s, state, SOL_SOCKET,
|
312
|
+
SO_LINGER, &opt, sizeof(opt), ignored_ec);
|
313
|
+
}
|
314
|
+
|
315
|
+
clear_last_error();
|
316
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
317
|
+
result = error_wrapper(::closesocket(s), ec);
|
318
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
319
|
+
result = error_wrapper(::close(s), ec);
|
320
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
321
|
+
|
322
|
+
if (result != 0
|
323
|
+
&& (ec == boost::asio::error::would_block
|
324
|
+
|| ec == boost::asio::error::try_again))
|
325
|
+
{
|
326
|
+
// According to UNIX Network Programming Vol. 1, it is possible for
|
327
|
+
// close() to fail with EWOULDBLOCK under certain circumstances. What
|
328
|
+
// isn't clear is the state of the descriptor after this error. The one
|
329
|
+
// current OS where this behaviour is seen, Windows, says that the socket
|
330
|
+
// remains open. Therefore we'll put the descriptor back into blocking
|
331
|
+
// mode and have another attempt at closing it.
|
332
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
333
|
+
ioctl_arg_type arg = 0;
|
334
|
+
::ioctlsocket(s, FIONBIO, &arg);
|
335
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
336
|
+
# if defined(__SYMBIAN32__)
|
337
|
+
int flags = ::fcntl(s, F_GETFL, 0);
|
338
|
+
if (flags >= 0)
|
339
|
+
::fcntl(s, F_SETFL, flags & ~O_NONBLOCK);
|
340
|
+
# else // defined(__SYMBIAN32__)
|
341
|
+
ioctl_arg_type arg = 0;
|
342
|
+
::ioctl(s, FIONBIO, &arg);
|
343
|
+
# endif // defined(__SYMBIAN32__)
|
344
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
345
|
+
state &= ~non_blocking;
|
346
|
+
|
347
|
+
clear_last_error();
|
348
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
349
|
+
result = error_wrapper(::closesocket(s), ec);
|
350
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
351
|
+
result = error_wrapper(::close(s), ec);
|
352
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
if (result == 0)
|
357
|
+
ec = boost::system::error_code();
|
358
|
+
return result;
|
359
|
+
}
|
360
|
+
|
361
|
+
bool set_user_non_blocking(socket_type s,
|
362
|
+
state_type& state, bool value, boost::system::error_code& ec)
|
363
|
+
{
|
364
|
+
if (s == invalid_socket)
|
365
|
+
{
|
366
|
+
ec = boost::asio::error::bad_descriptor;
|
367
|
+
return false;
|
368
|
+
}
|
369
|
+
|
370
|
+
clear_last_error();
|
371
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
372
|
+
ioctl_arg_type arg = (value ? 1 : 0);
|
373
|
+
int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec);
|
374
|
+
#elif defined(__SYMBIAN32__)
|
375
|
+
int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec);
|
376
|
+
if (result >= 0)
|
377
|
+
{
|
378
|
+
clear_last_error();
|
379
|
+
int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
|
380
|
+
result = error_wrapper(::fcntl(s, F_SETFL, flag), ec);
|
381
|
+
}
|
382
|
+
#else
|
383
|
+
ioctl_arg_type arg = (value ? 1 : 0);
|
384
|
+
int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
|
385
|
+
#endif
|
386
|
+
|
387
|
+
if (result >= 0)
|
388
|
+
{
|
389
|
+
ec = boost::system::error_code();
|
390
|
+
if (value)
|
391
|
+
state |= user_set_non_blocking;
|
392
|
+
else
|
393
|
+
{
|
394
|
+
// Clearing the user-set non-blocking mode always overrides any
|
395
|
+
// internally-set non-blocking flag. Any subsequent asynchronous
|
396
|
+
// operations will need to re-enable non-blocking I/O.
|
397
|
+
state &= ~(user_set_non_blocking | internal_non_blocking);
|
398
|
+
}
|
399
|
+
return true;
|
400
|
+
}
|
401
|
+
|
402
|
+
return false;
|
403
|
+
}
|
404
|
+
|
405
|
+
bool set_internal_non_blocking(socket_type s,
|
406
|
+
state_type& state, bool value, boost::system::error_code& ec)
|
407
|
+
{
|
408
|
+
if (s == invalid_socket)
|
409
|
+
{
|
410
|
+
ec = boost::asio::error::bad_descriptor;
|
411
|
+
return false;
|
412
|
+
}
|
413
|
+
|
414
|
+
if (!value && (state & user_set_non_blocking))
|
415
|
+
{
|
416
|
+
// It does not make sense to clear the internal non-blocking flag if the
|
417
|
+
// user still wants non-blocking behaviour. Return an error and let the
|
418
|
+
// caller figure out whether to update the user-set non-blocking flag.
|
419
|
+
ec = boost::asio::error::invalid_argument;
|
420
|
+
return false;
|
421
|
+
}
|
422
|
+
|
423
|
+
clear_last_error();
|
424
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
425
|
+
ioctl_arg_type arg = (value ? 1 : 0);
|
426
|
+
int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec);
|
427
|
+
#elif defined(__SYMBIAN32__)
|
428
|
+
int result = error_wrapper(::fcntl(s, F_GETFL, 0), ec);
|
429
|
+
if (result >= 0)
|
430
|
+
{
|
431
|
+
clear_last_error();
|
432
|
+
int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
|
433
|
+
result = error_wrapper(::fcntl(s, F_SETFL, flag), ec);
|
434
|
+
}
|
435
|
+
#else
|
436
|
+
ioctl_arg_type arg = (value ? 1 : 0);
|
437
|
+
int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
|
438
|
+
#endif
|
439
|
+
|
440
|
+
if (result >= 0)
|
441
|
+
{
|
442
|
+
ec = boost::system::error_code();
|
443
|
+
if (value)
|
444
|
+
state |= internal_non_blocking;
|
445
|
+
else
|
446
|
+
state &= ~internal_non_blocking;
|
447
|
+
return true;
|
448
|
+
}
|
449
|
+
|
450
|
+
return false;
|
451
|
+
}
|
452
|
+
|
453
|
+
int shutdown(socket_type s, int what, boost::system::error_code& ec)
|
454
|
+
{
|
455
|
+
if (s == invalid_socket)
|
456
|
+
{
|
457
|
+
ec = boost::asio::error::bad_descriptor;
|
458
|
+
return socket_error_retval;
|
459
|
+
}
|
460
|
+
|
461
|
+
clear_last_error();
|
462
|
+
int result = error_wrapper(::shutdown(s, what), ec);
|
463
|
+
if (result == 0)
|
464
|
+
ec = boost::system::error_code();
|
465
|
+
return result;
|
466
|
+
}
|
467
|
+
|
468
|
+
template <typename SockLenType>
|
469
|
+
inline int call_connect(SockLenType msghdr::*,
|
470
|
+
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
|
471
|
+
{
|
472
|
+
return ::connect(s, addr, (SockLenType)addrlen);
|
473
|
+
}
|
474
|
+
|
475
|
+
int connect(socket_type s, const socket_addr_type* addr,
|
476
|
+
std::size_t addrlen, boost::system::error_code& ec)
|
477
|
+
{
|
478
|
+
if (s == invalid_socket)
|
479
|
+
{
|
480
|
+
ec = boost::asio::error::bad_descriptor;
|
481
|
+
return socket_error_retval;
|
482
|
+
}
|
483
|
+
|
484
|
+
clear_last_error();
|
485
|
+
int result = error_wrapper(call_connect(
|
486
|
+
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
487
|
+
if (result == 0)
|
488
|
+
ec = boost::system::error_code();
|
489
|
+
#if defined(__linux__)
|
490
|
+
else if (ec == boost::asio::error::try_again)
|
491
|
+
ec = boost::asio::error::no_buffer_space;
|
492
|
+
#endif // defined(__linux__)
|
493
|
+
return result;
|
494
|
+
}
|
495
|
+
|
496
|
+
void sync_connect(socket_type s, const socket_addr_type* addr,
|
497
|
+
std::size_t addrlen, boost::system::error_code& ec)
|
498
|
+
{
|
499
|
+
// Perform the connect operation.
|
500
|
+
socket_ops::connect(s, addr, addrlen, ec);
|
501
|
+
if (ec != boost::asio::error::in_progress
|
502
|
+
&& ec != boost::asio::error::would_block)
|
503
|
+
{
|
504
|
+
// The connect operation finished immediately.
|
505
|
+
return;
|
506
|
+
}
|
507
|
+
|
508
|
+
// Wait for socket to become ready.
|
509
|
+
if (socket_ops::poll_connect(s, ec) < 0)
|
510
|
+
return;
|
511
|
+
|
512
|
+
// Get the error code from the connect operation.
|
513
|
+
int connect_error = 0;
|
514
|
+
size_t connect_error_len = sizeof(connect_error);
|
515
|
+
if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
|
516
|
+
&connect_error, &connect_error_len, ec) == socket_error_retval)
|
517
|
+
return;
|
518
|
+
|
519
|
+
// Return the result of the connect operation.
|
520
|
+
ec = boost::system::error_code(connect_error,
|
521
|
+
boost::asio::error::get_system_category());
|
522
|
+
}
|
523
|
+
|
524
|
+
#if defined(BOOST_ASIO_HAS_IOCP)
|
525
|
+
|
526
|
+
void complete_iocp_connect(socket_type s, boost::system::error_code& ec)
|
527
|
+
{
|
528
|
+
// Map non-portable errors to their portable counterparts.
|
529
|
+
switch (ec.value())
|
530
|
+
{
|
531
|
+
case ERROR_CONNECTION_REFUSED:
|
532
|
+
ec = boost::asio::error::connection_refused;
|
533
|
+
break;
|
534
|
+
case ERROR_NETWORK_UNREACHABLE:
|
535
|
+
ec = boost::asio::error::network_unreachable;
|
536
|
+
break;
|
537
|
+
case ERROR_HOST_UNREACHABLE:
|
538
|
+
ec = boost::asio::error::host_unreachable;
|
539
|
+
break;
|
540
|
+
case ERROR_SEM_TIMEOUT:
|
541
|
+
ec = boost::asio::error::timed_out;
|
542
|
+
break;
|
543
|
+
default:
|
544
|
+
break;
|
545
|
+
}
|
546
|
+
|
547
|
+
if (!ec)
|
548
|
+
{
|
549
|
+
// Need to set the SO_UPDATE_CONNECT_CONTEXT option so that getsockname
|
550
|
+
// and getpeername will work on the connected socket.
|
551
|
+
socket_ops::state_type state = 0;
|
552
|
+
const int so_update_connect_context = 0x7010;
|
553
|
+
socket_ops::setsockopt(s, state, SOL_SOCKET,
|
554
|
+
so_update_connect_context, 0, 0, ec);
|
555
|
+
}
|
556
|
+
}
|
557
|
+
|
558
|
+
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
559
|
+
|
560
|
+
bool non_blocking_connect(socket_type s, boost::system::error_code& ec)
|
561
|
+
{
|
562
|
+
// Check if the connect operation has finished. This is required since we may
|
563
|
+
// get spurious readiness notifications from the reactor.
|
564
|
+
#if defined(BOOST_ASIO_WINDOWS) \
|
565
|
+
|| defined(__CYGWIN__) \
|
566
|
+
|| defined(__SYMBIAN32__)
|
567
|
+
fd_set write_fds;
|
568
|
+
FD_ZERO(&write_fds);
|
569
|
+
FD_SET(s, &write_fds);
|
570
|
+
fd_set except_fds;
|
571
|
+
FD_ZERO(&except_fds);
|
572
|
+
FD_SET(s, &except_fds);
|
573
|
+
timeval zero_timeout;
|
574
|
+
zero_timeout.tv_sec = 0;
|
575
|
+
zero_timeout.tv_usec = 0;
|
576
|
+
int ready = ::select(s + 1, 0, &write_fds, &except_fds, &zero_timeout);
|
577
|
+
#else // defined(BOOST_ASIO_WINDOWS)
|
578
|
+
// || defined(__CYGWIN__)
|
579
|
+
// || defined(__SYMBIAN32__)
|
580
|
+
pollfd fds;
|
581
|
+
fds.fd = s;
|
582
|
+
fds.events = POLLOUT;
|
583
|
+
fds.revents = 0;
|
584
|
+
int ready = ::poll(&fds, 1, 0);
|
585
|
+
#endif // defined(BOOST_ASIO_WINDOWS)
|
586
|
+
// || defined(__CYGWIN__)
|
587
|
+
// || defined(__SYMBIAN32__)
|
588
|
+
if (ready == 0)
|
589
|
+
{
|
590
|
+
// The asynchronous connect operation is still in progress.
|
591
|
+
return false;
|
592
|
+
}
|
593
|
+
|
594
|
+
// Get the error code from the connect operation.
|
595
|
+
int connect_error = 0;
|
596
|
+
size_t connect_error_len = sizeof(connect_error);
|
597
|
+
if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
|
598
|
+
&connect_error, &connect_error_len, ec) == 0)
|
599
|
+
{
|
600
|
+
if (connect_error)
|
601
|
+
{
|
602
|
+
ec = boost::system::error_code(connect_error,
|
603
|
+
boost::asio::error::get_system_category());
|
604
|
+
}
|
605
|
+
else
|
606
|
+
ec = boost::system::error_code();
|
607
|
+
}
|
608
|
+
|
609
|
+
return true;
|
610
|
+
}
|
611
|
+
|
612
|
+
int socketpair(int af, int type, int protocol,
|
613
|
+
socket_type sv[2], boost::system::error_code& ec)
|
614
|
+
{
|
615
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
616
|
+
(void)(af);
|
617
|
+
(void)(type);
|
618
|
+
(void)(protocol);
|
619
|
+
(void)(sv);
|
620
|
+
ec = boost::asio::error::operation_not_supported;
|
621
|
+
return socket_error_retval;
|
622
|
+
#else
|
623
|
+
clear_last_error();
|
624
|
+
int result = error_wrapper(::socketpair(af, type, protocol, sv), ec);
|
625
|
+
if (result == 0)
|
626
|
+
ec = boost::system::error_code();
|
627
|
+
return result;
|
628
|
+
#endif
|
629
|
+
}
|
630
|
+
|
631
|
+
bool sockatmark(socket_type s, boost::system::error_code& ec)
|
632
|
+
{
|
633
|
+
if (s == invalid_socket)
|
634
|
+
{
|
635
|
+
ec = boost::asio::error::bad_descriptor;
|
636
|
+
return false;
|
637
|
+
}
|
638
|
+
|
639
|
+
#if defined(SIOCATMARK)
|
640
|
+
ioctl_arg_type value = 0;
|
641
|
+
# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
642
|
+
int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec);
|
643
|
+
# else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
644
|
+
int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec);
|
645
|
+
# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
646
|
+
if (result == 0)
|
647
|
+
ec = boost::system::error_code();
|
648
|
+
# if defined(ENOTTY)
|
649
|
+
if (ec.value() == ENOTTY)
|
650
|
+
ec = boost::asio::error::not_socket;
|
651
|
+
# endif // defined(ENOTTY)
|
652
|
+
#else // defined(SIOCATMARK)
|
653
|
+
int value = error_wrapper(::sockatmark(s), ec);
|
654
|
+
if (value != -1)
|
655
|
+
ec = boost::system::error_code();
|
656
|
+
#endif // defined(SIOCATMARK)
|
657
|
+
|
658
|
+
return ec ? false : value != 0;
|
659
|
+
}
|
660
|
+
|
661
|
+
size_t available(socket_type s, boost::system::error_code& ec)
|
662
|
+
{
|
663
|
+
if (s == invalid_socket)
|
664
|
+
{
|
665
|
+
ec = boost::asio::error::bad_descriptor;
|
666
|
+
return 0;
|
667
|
+
}
|
668
|
+
|
669
|
+
ioctl_arg_type value = 0;
|
670
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
671
|
+
int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec);
|
672
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
673
|
+
int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec);
|
674
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
675
|
+
if (result == 0)
|
676
|
+
ec = boost::system::error_code();
|
677
|
+
#if defined(ENOTTY)
|
678
|
+
if (ec.value() == ENOTTY)
|
679
|
+
ec = boost::asio::error::not_socket;
|
680
|
+
#endif // defined(ENOTTY)
|
681
|
+
|
682
|
+
return ec ? static_cast<size_t>(0) : static_cast<size_t>(value);
|
683
|
+
}
|
684
|
+
|
685
|
+
int listen(socket_type s, int backlog, boost::system::error_code& ec)
|
686
|
+
{
|
687
|
+
if (s == invalid_socket)
|
688
|
+
{
|
689
|
+
ec = boost::asio::error::bad_descriptor;
|
690
|
+
return socket_error_retval;
|
691
|
+
}
|
692
|
+
|
693
|
+
clear_last_error();
|
694
|
+
int result = error_wrapper(::listen(s, backlog), ec);
|
695
|
+
if (result == 0)
|
696
|
+
ec = boost::system::error_code();
|
697
|
+
return result;
|
698
|
+
}
|
699
|
+
|
700
|
+
inline void init_buf_iov_base(void*& base, void* addr)
|
701
|
+
{
|
702
|
+
base = addr;
|
703
|
+
}
|
704
|
+
|
705
|
+
template <typename T>
|
706
|
+
inline void init_buf_iov_base(T& base, void* addr)
|
707
|
+
{
|
708
|
+
base = static_cast<T>(addr);
|
709
|
+
}
|
710
|
+
|
711
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
712
|
+
typedef WSABUF buf;
|
713
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
714
|
+
typedef iovec buf;
|
715
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
716
|
+
|
717
|
+
void init_buf(buf& b, void* data, size_t size)
|
718
|
+
{
|
719
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
720
|
+
b.buf = static_cast<char*>(data);
|
721
|
+
b.len = static_cast<u_long>(size);
|
722
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
723
|
+
init_buf_iov_base(b.iov_base, data);
|
724
|
+
b.iov_len = size;
|
725
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
726
|
+
}
|
727
|
+
|
728
|
+
void init_buf(buf& b, const void* data, size_t size)
|
729
|
+
{
|
730
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
731
|
+
b.buf = static_cast<char*>(const_cast<void*>(data));
|
732
|
+
b.len = static_cast<u_long>(size);
|
733
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
734
|
+
init_buf_iov_base(b.iov_base, const_cast<void*>(data));
|
735
|
+
b.iov_len = size;
|
736
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
737
|
+
}
|
738
|
+
|
739
|
+
inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
|
740
|
+
{
|
741
|
+
name = addr;
|
742
|
+
}
|
743
|
+
|
744
|
+
inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
|
745
|
+
{
|
746
|
+
name = const_cast<socket_addr_type*>(addr);
|
747
|
+
}
|
748
|
+
|
749
|
+
template <typename T>
|
750
|
+
inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
|
751
|
+
{
|
752
|
+
name = reinterpret_cast<T>(addr);
|
753
|
+
}
|
754
|
+
|
755
|
+
template <typename T>
|
756
|
+
inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
|
757
|
+
{
|
758
|
+
name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
|
759
|
+
}
|
760
|
+
|
761
|
+
signed_size_type recv(socket_type s, buf* bufs, size_t count,
|
762
|
+
int flags, boost::system::error_code& ec)
|
763
|
+
{
|
764
|
+
clear_last_error();
|
765
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
766
|
+
// Receive some data.
|
767
|
+
DWORD recv_buf_count = static_cast<DWORD>(count);
|
768
|
+
DWORD bytes_transferred = 0;
|
769
|
+
DWORD recv_flags = flags;
|
770
|
+
int result = error_wrapper(::WSARecv(s, bufs,
|
771
|
+
recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
|
772
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
773
|
+
ec = boost::asio::error::connection_reset;
|
774
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
775
|
+
ec = boost::asio::error::connection_refused;
|
776
|
+
if (result != 0)
|
777
|
+
return socket_error_retval;
|
778
|
+
ec = boost::system::error_code();
|
779
|
+
return bytes_transferred;
|
780
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
781
|
+
msghdr msg = msghdr();
|
782
|
+
msg.msg_iov = bufs;
|
783
|
+
msg.msg_iovlen = static_cast<int>(count);
|
784
|
+
signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
|
785
|
+
if (result >= 0)
|
786
|
+
ec = boost::system::error_code();
|
787
|
+
return result;
|
788
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
789
|
+
}
|
790
|
+
|
791
|
+
size_t sync_recv(socket_type s, state_type state, buf* bufs,
|
792
|
+
size_t count, int flags, bool all_empty, boost::system::error_code& ec)
|
793
|
+
{
|
794
|
+
if (s == invalid_socket)
|
795
|
+
{
|
796
|
+
ec = boost::asio::error::bad_descriptor;
|
797
|
+
return 0;
|
798
|
+
}
|
799
|
+
|
800
|
+
// A request to read 0 bytes on a stream is a no-op.
|
801
|
+
if (all_empty && (state & stream_oriented))
|
802
|
+
{
|
803
|
+
ec = boost::system::error_code();
|
804
|
+
return 0;
|
805
|
+
}
|
806
|
+
|
807
|
+
// Read some data.
|
808
|
+
for (;;)
|
809
|
+
{
|
810
|
+
// Try to complete the operation without blocking.
|
811
|
+
signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
|
812
|
+
|
813
|
+
// Check if operation succeeded.
|
814
|
+
if (bytes > 0)
|
815
|
+
return bytes;
|
816
|
+
|
817
|
+
// Check for EOF.
|
818
|
+
if ((state & stream_oriented) && bytes == 0)
|
819
|
+
{
|
820
|
+
ec = boost::asio::error::eof;
|
821
|
+
return 0;
|
822
|
+
}
|
823
|
+
|
824
|
+
// Operation failed.
|
825
|
+
if ((state & user_set_non_blocking)
|
826
|
+
|| (ec != boost::asio::error::would_block
|
827
|
+
&& ec != boost::asio::error::try_again))
|
828
|
+
return 0;
|
829
|
+
|
830
|
+
// Wait for socket to become ready.
|
831
|
+
if (socket_ops::poll_read(s, 0, ec) < 0)
|
832
|
+
return 0;
|
833
|
+
}
|
834
|
+
}
|
835
|
+
|
836
|
+
#if defined(BOOST_ASIO_HAS_IOCP)
|
837
|
+
|
838
|
+
void complete_iocp_recv(state_type state,
|
839
|
+
const weak_cancel_token_type& cancel_token, bool all_empty,
|
840
|
+
boost::system::error_code& ec, size_t bytes_transferred)
|
841
|
+
{
|
842
|
+
// Map non-portable errors to their portable counterparts.
|
843
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
844
|
+
{
|
845
|
+
if (cancel_token.expired())
|
846
|
+
ec = boost::asio::error::operation_aborted;
|
847
|
+
else
|
848
|
+
ec = boost::asio::error::connection_reset;
|
849
|
+
}
|
850
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
851
|
+
{
|
852
|
+
ec = boost::asio::error::connection_refused;
|
853
|
+
}
|
854
|
+
|
855
|
+
// Check for connection closed.
|
856
|
+
else if (!ec && bytes_transferred == 0
|
857
|
+
&& (state & stream_oriented) != 0
|
858
|
+
&& !all_empty)
|
859
|
+
{
|
860
|
+
ec = boost::asio::error::eof;
|
861
|
+
}
|
862
|
+
}
|
863
|
+
|
864
|
+
#else // defined(BOOST_ASIO_HAS_IOCP)
|
865
|
+
|
866
|
+
bool non_blocking_recv(socket_type s,
|
867
|
+
buf* bufs, size_t count, int flags, bool is_stream,
|
868
|
+
boost::system::error_code& ec, size_t& bytes_transferred)
|
869
|
+
{
|
870
|
+
for (;;)
|
871
|
+
{
|
872
|
+
// Read some data.
|
873
|
+
signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);
|
874
|
+
|
875
|
+
// Check for end of stream.
|
876
|
+
if (is_stream && bytes == 0)
|
877
|
+
{
|
878
|
+
ec = boost::asio::error::eof;
|
879
|
+
return true;
|
880
|
+
}
|
881
|
+
|
882
|
+
// Retry operation if interrupted by signal.
|
883
|
+
if (ec == boost::asio::error::interrupted)
|
884
|
+
continue;
|
885
|
+
|
886
|
+
// Check if we need to run the operation again.
|
887
|
+
if (ec == boost::asio::error::would_block
|
888
|
+
|| ec == boost::asio::error::try_again)
|
889
|
+
return false;
|
890
|
+
|
891
|
+
// Operation is complete.
|
892
|
+
if (bytes >= 0)
|
893
|
+
{
|
894
|
+
ec = boost::system::error_code();
|
895
|
+
bytes_transferred = bytes;
|
896
|
+
}
|
897
|
+
else
|
898
|
+
bytes_transferred = 0;
|
899
|
+
|
900
|
+
return true;
|
901
|
+
}
|
902
|
+
}
|
903
|
+
|
904
|
+
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
905
|
+
|
906
|
+
signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
|
907
|
+
int flags, socket_addr_type* addr, std::size_t* addrlen,
|
908
|
+
boost::system::error_code& ec)
|
909
|
+
{
|
910
|
+
clear_last_error();
|
911
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
912
|
+
// Receive some data.
|
913
|
+
DWORD recv_buf_count = static_cast<DWORD>(count);
|
914
|
+
DWORD bytes_transferred = 0;
|
915
|
+
DWORD recv_flags = flags;
|
916
|
+
int tmp_addrlen = (int)*addrlen;
|
917
|
+
int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
|
918
|
+
&bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
|
919
|
+
*addrlen = (std::size_t)tmp_addrlen;
|
920
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
921
|
+
ec = boost::asio::error::connection_reset;
|
922
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
923
|
+
ec = boost::asio::error::connection_refused;
|
924
|
+
if (result != 0)
|
925
|
+
return socket_error_retval;
|
926
|
+
ec = boost::system::error_code();
|
927
|
+
return bytes_transferred;
|
928
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
929
|
+
msghdr msg = msghdr();
|
930
|
+
init_msghdr_msg_name(msg.msg_name, addr);
|
931
|
+
msg.msg_namelen = static_cast<int>(*addrlen);
|
932
|
+
msg.msg_iov = bufs;
|
933
|
+
msg.msg_iovlen = static_cast<int>(count);
|
934
|
+
signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
|
935
|
+
*addrlen = msg.msg_namelen;
|
936
|
+
if (result >= 0)
|
937
|
+
ec = boost::system::error_code();
|
938
|
+
return result;
|
939
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
940
|
+
}
|
941
|
+
|
942
|
+
size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
|
943
|
+
size_t count, int flags, socket_addr_type* addr,
|
944
|
+
std::size_t* addrlen, boost::system::error_code& ec)
|
945
|
+
{
|
946
|
+
if (s == invalid_socket)
|
947
|
+
{
|
948
|
+
ec = boost::asio::error::bad_descriptor;
|
949
|
+
return 0;
|
950
|
+
}
|
951
|
+
|
952
|
+
// Read some data.
|
953
|
+
for (;;)
|
954
|
+
{
|
955
|
+
// Try to complete the operation without blocking.
|
956
|
+
signed_size_type bytes = socket_ops::recvfrom(
|
957
|
+
s, bufs, count, flags, addr, addrlen, ec);
|
958
|
+
|
959
|
+
// Check if operation succeeded.
|
960
|
+
if (bytes >= 0)
|
961
|
+
return bytes;
|
962
|
+
|
963
|
+
// Operation failed.
|
964
|
+
if ((state & user_set_non_blocking)
|
965
|
+
|| (ec != boost::asio::error::would_block
|
966
|
+
&& ec != boost::asio::error::try_again))
|
967
|
+
return 0;
|
968
|
+
|
969
|
+
// Wait for socket to become ready.
|
970
|
+
if (socket_ops::poll_read(s, 0, ec) < 0)
|
971
|
+
return 0;
|
972
|
+
}
|
973
|
+
}
|
974
|
+
|
975
|
+
#if defined(BOOST_ASIO_HAS_IOCP)
|
976
|
+
|
977
|
+
void complete_iocp_recvfrom(
|
978
|
+
const weak_cancel_token_type& cancel_token,
|
979
|
+
boost::system::error_code& ec)
|
980
|
+
{
|
981
|
+
// Map non-portable errors to their portable counterparts.
|
982
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
983
|
+
{
|
984
|
+
if (cancel_token.expired())
|
985
|
+
ec = boost::asio::error::operation_aborted;
|
986
|
+
else
|
987
|
+
ec = boost::asio::error::connection_reset;
|
988
|
+
}
|
989
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
990
|
+
{
|
991
|
+
ec = boost::asio::error::connection_refused;
|
992
|
+
}
|
993
|
+
}
|
994
|
+
|
995
|
+
#else // defined(BOOST_ASIO_HAS_IOCP)
|
996
|
+
|
997
|
+
bool non_blocking_recvfrom(socket_type s,
|
998
|
+
buf* bufs, size_t count, int flags,
|
999
|
+
socket_addr_type* addr, std::size_t* addrlen,
|
1000
|
+
boost::system::error_code& ec, size_t& bytes_transferred)
|
1001
|
+
{
|
1002
|
+
for (;;)
|
1003
|
+
{
|
1004
|
+
// Read some data.
|
1005
|
+
signed_size_type bytes = socket_ops::recvfrom(
|
1006
|
+
s, bufs, count, flags, addr, addrlen, ec);
|
1007
|
+
|
1008
|
+
// Retry operation if interrupted by signal.
|
1009
|
+
if (ec == boost::asio::error::interrupted)
|
1010
|
+
continue;
|
1011
|
+
|
1012
|
+
// Check if we need to run the operation again.
|
1013
|
+
if (ec == boost::asio::error::would_block
|
1014
|
+
|| ec == boost::asio::error::try_again)
|
1015
|
+
return false;
|
1016
|
+
|
1017
|
+
// Operation is complete.
|
1018
|
+
if (bytes >= 0)
|
1019
|
+
{
|
1020
|
+
ec = boost::system::error_code();
|
1021
|
+
bytes_transferred = bytes;
|
1022
|
+
}
|
1023
|
+
else
|
1024
|
+
bytes_transferred = 0;
|
1025
|
+
|
1026
|
+
return true;
|
1027
|
+
}
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
1031
|
+
|
1032
|
+
signed_size_type recvmsg(socket_type s, buf* bufs, size_t count,
|
1033
|
+
int in_flags, int& out_flags, boost::system::error_code& ec)
|
1034
|
+
{
|
1035
|
+
clear_last_error();
|
1036
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1037
|
+
out_flags = 0;
|
1038
|
+
return socket_ops::recv(s, bufs, count, in_flags, ec);
|
1039
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1040
|
+
msghdr msg = msghdr();
|
1041
|
+
msg.msg_iov = bufs;
|
1042
|
+
msg.msg_iovlen = static_cast<int>(count);
|
1043
|
+
signed_size_type result = error_wrapper(::recvmsg(s, &msg, in_flags), ec);
|
1044
|
+
if (result >= 0)
|
1045
|
+
{
|
1046
|
+
ec = boost::system::error_code();
|
1047
|
+
out_flags = msg.msg_flags;
|
1048
|
+
}
|
1049
|
+
else
|
1050
|
+
out_flags = 0;
|
1051
|
+
return result;
|
1052
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
size_t sync_recvmsg(socket_type s, state_type state,
|
1056
|
+
buf* bufs, size_t count, int in_flags, int& out_flags,
|
1057
|
+
boost::system::error_code& ec)
|
1058
|
+
{
|
1059
|
+
if (s == invalid_socket)
|
1060
|
+
{
|
1061
|
+
ec = boost::asio::error::bad_descriptor;
|
1062
|
+
return 0;
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
// Read some data.
|
1066
|
+
for (;;)
|
1067
|
+
{
|
1068
|
+
// Try to complete the operation without blocking.
|
1069
|
+
signed_size_type bytes = socket_ops::recvmsg(
|
1070
|
+
s, bufs, count, in_flags, out_flags, ec);
|
1071
|
+
|
1072
|
+
// Check if operation succeeded.
|
1073
|
+
if (bytes >= 0)
|
1074
|
+
return bytes;
|
1075
|
+
|
1076
|
+
// Operation failed.
|
1077
|
+
if ((state & user_set_non_blocking)
|
1078
|
+
|| (ec != boost::asio::error::would_block
|
1079
|
+
&& ec != boost::asio::error::try_again))
|
1080
|
+
return 0;
|
1081
|
+
|
1082
|
+
// Wait for socket to become ready.
|
1083
|
+
if (socket_ops::poll_read(s, 0, ec) < 0)
|
1084
|
+
return 0;
|
1085
|
+
}
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
#if defined(BOOST_ASIO_HAS_IOCP)
|
1089
|
+
|
1090
|
+
void complete_iocp_recvmsg(
|
1091
|
+
const weak_cancel_token_type& cancel_token,
|
1092
|
+
boost::system::error_code& ec)
|
1093
|
+
{
|
1094
|
+
// Map non-portable errors to their portable counterparts.
|
1095
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
1096
|
+
{
|
1097
|
+
if (cancel_token.expired())
|
1098
|
+
ec = boost::asio::error::operation_aborted;
|
1099
|
+
else
|
1100
|
+
ec = boost::asio::error::connection_reset;
|
1101
|
+
}
|
1102
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
1103
|
+
{
|
1104
|
+
ec = boost::asio::error::connection_refused;
|
1105
|
+
}
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
#else // defined(BOOST_ASIO_HAS_IOCP)
|
1109
|
+
|
1110
|
+
bool non_blocking_recvmsg(socket_type s,
|
1111
|
+
buf* bufs, size_t count, int in_flags, int& out_flags,
|
1112
|
+
boost::system::error_code& ec, size_t& bytes_transferred)
|
1113
|
+
{
|
1114
|
+
for (;;)
|
1115
|
+
{
|
1116
|
+
// Read some data.
|
1117
|
+
signed_size_type bytes = socket_ops::recvmsg(
|
1118
|
+
s, bufs, count, in_flags, out_flags, ec);
|
1119
|
+
|
1120
|
+
// Retry operation if interrupted by signal.
|
1121
|
+
if (ec == boost::asio::error::interrupted)
|
1122
|
+
continue;
|
1123
|
+
|
1124
|
+
// Check if we need to run the operation again.
|
1125
|
+
if (ec == boost::asio::error::would_block
|
1126
|
+
|| ec == boost::asio::error::try_again)
|
1127
|
+
return false;
|
1128
|
+
|
1129
|
+
// Operation is complete.
|
1130
|
+
if (bytes >= 0)
|
1131
|
+
{
|
1132
|
+
ec = boost::system::error_code();
|
1133
|
+
bytes_transferred = bytes;
|
1134
|
+
}
|
1135
|
+
else
|
1136
|
+
bytes_transferred = 0;
|
1137
|
+
|
1138
|
+
return true;
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
|
1142
|
+
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
1143
|
+
|
1144
|
+
signed_size_type send(socket_type s, const buf* bufs, size_t count,
|
1145
|
+
int flags, boost::system::error_code& ec)
|
1146
|
+
{
|
1147
|
+
clear_last_error();
|
1148
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1149
|
+
// Send the data.
|
1150
|
+
DWORD send_buf_count = static_cast<DWORD>(count);
|
1151
|
+
DWORD bytes_transferred = 0;
|
1152
|
+
DWORD send_flags = flags;
|
1153
|
+
int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs),
|
1154
|
+
send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
|
1155
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
1156
|
+
ec = boost::asio::error::connection_reset;
|
1157
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
1158
|
+
ec = boost::asio::error::connection_refused;
|
1159
|
+
if (result != 0)
|
1160
|
+
return socket_error_retval;
|
1161
|
+
ec = boost::system::error_code();
|
1162
|
+
return bytes_transferred;
|
1163
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1164
|
+
msghdr msg = msghdr();
|
1165
|
+
msg.msg_iov = const_cast<buf*>(bufs);
|
1166
|
+
msg.msg_iovlen = static_cast<int>(count);
|
1167
|
+
#if defined(__linux__)
|
1168
|
+
flags |= MSG_NOSIGNAL;
|
1169
|
+
#endif // defined(__linux__)
|
1170
|
+
signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
|
1171
|
+
if (result >= 0)
|
1172
|
+
ec = boost::system::error_code();
|
1173
|
+
return result;
|
1174
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1175
|
+
}
|
1176
|
+
|
1177
|
+
size_t sync_send(socket_type s, state_type state, const buf* bufs,
|
1178
|
+
size_t count, int flags, bool all_empty, boost::system::error_code& ec)
|
1179
|
+
{
|
1180
|
+
if (s == invalid_socket)
|
1181
|
+
{
|
1182
|
+
ec = boost::asio::error::bad_descriptor;
|
1183
|
+
return 0;
|
1184
|
+
}
|
1185
|
+
|
1186
|
+
// A request to write 0 bytes to a stream is a no-op.
|
1187
|
+
if (all_empty && (state & stream_oriented))
|
1188
|
+
{
|
1189
|
+
ec = boost::system::error_code();
|
1190
|
+
return 0;
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
// Read some data.
|
1194
|
+
for (;;)
|
1195
|
+
{
|
1196
|
+
// Try to complete the operation without blocking.
|
1197
|
+
signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
|
1198
|
+
|
1199
|
+
// Check if operation succeeded.
|
1200
|
+
if (bytes >= 0)
|
1201
|
+
return bytes;
|
1202
|
+
|
1203
|
+
// Operation failed.
|
1204
|
+
if ((state & user_set_non_blocking)
|
1205
|
+
|| (ec != boost::asio::error::would_block
|
1206
|
+
&& ec != boost::asio::error::try_again))
|
1207
|
+
return 0;
|
1208
|
+
|
1209
|
+
// Wait for socket to become ready.
|
1210
|
+
if (socket_ops::poll_write(s, 0, ec) < 0)
|
1211
|
+
return 0;
|
1212
|
+
}
|
1213
|
+
}
|
1214
|
+
|
1215
|
+
#if defined(BOOST_ASIO_HAS_IOCP)
|
1216
|
+
|
1217
|
+
void complete_iocp_send(
|
1218
|
+
const weak_cancel_token_type& cancel_token,
|
1219
|
+
boost::system::error_code& ec)
|
1220
|
+
{
|
1221
|
+
// Map non-portable errors to their portable counterparts.
|
1222
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
1223
|
+
{
|
1224
|
+
if (cancel_token.expired())
|
1225
|
+
ec = boost::asio::error::operation_aborted;
|
1226
|
+
else
|
1227
|
+
ec = boost::asio::error::connection_reset;
|
1228
|
+
}
|
1229
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
1230
|
+
{
|
1231
|
+
ec = boost::asio::error::connection_refused;
|
1232
|
+
}
|
1233
|
+
}
|
1234
|
+
|
1235
|
+
#else // defined(BOOST_ASIO_HAS_IOCP)
|
1236
|
+
|
1237
|
+
bool non_blocking_send(socket_type s,
|
1238
|
+
const buf* bufs, size_t count, int flags,
|
1239
|
+
boost::system::error_code& ec, size_t& bytes_transferred)
|
1240
|
+
{
|
1241
|
+
for (;;)
|
1242
|
+
{
|
1243
|
+
// Write some data.
|
1244
|
+
signed_size_type bytes = socket_ops::send(s, bufs, count, flags, ec);
|
1245
|
+
|
1246
|
+
// Retry operation if interrupted by signal.
|
1247
|
+
if (ec == boost::asio::error::interrupted)
|
1248
|
+
continue;
|
1249
|
+
|
1250
|
+
// Check if we need to run the operation again.
|
1251
|
+
if (ec == boost::asio::error::would_block
|
1252
|
+
|| ec == boost::asio::error::try_again)
|
1253
|
+
return false;
|
1254
|
+
|
1255
|
+
// Operation is complete.
|
1256
|
+
if (bytes >= 0)
|
1257
|
+
{
|
1258
|
+
ec = boost::system::error_code();
|
1259
|
+
bytes_transferred = bytes;
|
1260
|
+
}
|
1261
|
+
else
|
1262
|
+
bytes_transferred = 0;
|
1263
|
+
|
1264
|
+
return true;
|
1265
|
+
}
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
#endif // defined(BOOST_ASIO_HAS_IOCP)
|
1269
|
+
|
1270
|
+
signed_size_type sendto(socket_type s, const buf* bufs, size_t count,
|
1271
|
+
int flags, const socket_addr_type* addr, std::size_t addrlen,
|
1272
|
+
boost::system::error_code& ec)
|
1273
|
+
{
|
1274
|
+
clear_last_error();
|
1275
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1276
|
+
// Send the data.
|
1277
|
+
DWORD send_buf_count = static_cast<DWORD>(count);
|
1278
|
+
DWORD bytes_transferred = 0;
|
1279
|
+
int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
|
1280
|
+
send_buf_count, &bytes_transferred, flags, addr,
|
1281
|
+
static_cast<int>(addrlen), 0, 0), ec);
|
1282
|
+
if (ec.value() == ERROR_NETNAME_DELETED)
|
1283
|
+
ec = boost::asio::error::connection_reset;
|
1284
|
+
else if (ec.value() == ERROR_PORT_UNREACHABLE)
|
1285
|
+
ec = boost::asio::error::connection_refused;
|
1286
|
+
if (result != 0)
|
1287
|
+
return socket_error_retval;
|
1288
|
+
ec = boost::system::error_code();
|
1289
|
+
return bytes_transferred;
|
1290
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1291
|
+
msghdr msg = msghdr();
|
1292
|
+
init_msghdr_msg_name(msg.msg_name, addr);
|
1293
|
+
msg.msg_namelen = static_cast<int>(addrlen);
|
1294
|
+
msg.msg_iov = const_cast<buf*>(bufs);
|
1295
|
+
msg.msg_iovlen = static_cast<int>(count);
|
1296
|
+
#if defined(__linux__)
|
1297
|
+
flags |= MSG_NOSIGNAL;
|
1298
|
+
#endif // defined(__linux__)
|
1299
|
+
signed_size_type result = error_wrapper(::sendmsg(s, &msg, flags), ec);
|
1300
|
+
if (result >= 0)
|
1301
|
+
ec = boost::system::error_code();
|
1302
|
+
return result;
|
1303
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1304
|
+
}
|
1305
|
+
|
1306
|
+
size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
|
1307
|
+
size_t count, int flags, const socket_addr_type* addr,
|
1308
|
+
std::size_t addrlen, boost::system::error_code& ec)
|
1309
|
+
{
|
1310
|
+
if (s == invalid_socket)
|
1311
|
+
{
|
1312
|
+
ec = boost::asio::error::bad_descriptor;
|
1313
|
+
return 0;
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
// Write some data.
|
1317
|
+
for (;;)
|
1318
|
+
{
|
1319
|
+
// Try to complete the operation without blocking.
|
1320
|
+
signed_size_type bytes = socket_ops::sendto(
|
1321
|
+
s, bufs, count, flags, addr, addrlen, ec);
|
1322
|
+
|
1323
|
+
// Check if operation succeeded.
|
1324
|
+
if (bytes >= 0)
|
1325
|
+
return bytes;
|
1326
|
+
|
1327
|
+
// Operation failed.
|
1328
|
+
if ((state & user_set_non_blocking)
|
1329
|
+
|| (ec != boost::asio::error::would_block
|
1330
|
+
&& ec != boost::asio::error::try_again))
|
1331
|
+
return 0;
|
1332
|
+
|
1333
|
+
// Wait for socket to become ready.
|
1334
|
+
if (socket_ops::poll_write(s, 0, ec) < 0)
|
1335
|
+
return 0;
|
1336
|
+
}
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
#if !defined(BOOST_ASIO_HAS_IOCP)
|
1340
|
+
|
1341
|
+
bool non_blocking_sendto(socket_type s,
|
1342
|
+
const buf* bufs, size_t count, int flags,
|
1343
|
+
const socket_addr_type* addr, std::size_t addrlen,
|
1344
|
+
boost::system::error_code& ec, size_t& bytes_transferred)
|
1345
|
+
{
|
1346
|
+
for (;;)
|
1347
|
+
{
|
1348
|
+
// Write some data.
|
1349
|
+
signed_size_type bytes = socket_ops::sendto(
|
1350
|
+
s, bufs, count, flags, addr, addrlen, ec);
|
1351
|
+
|
1352
|
+
// Retry operation if interrupted by signal.
|
1353
|
+
if (ec == boost::asio::error::interrupted)
|
1354
|
+
continue;
|
1355
|
+
|
1356
|
+
// Check if we need to run the operation again.
|
1357
|
+
if (ec == boost::asio::error::would_block
|
1358
|
+
|| ec == boost::asio::error::try_again)
|
1359
|
+
return false;
|
1360
|
+
|
1361
|
+
// Operation is complete.
|
1362
|
+
if (bytes >= 0)
|
1363
|
+
{
|
1364
|
+
ec = boost::system::error_code();
|
1365
|
+
bytes_transferred = bytes;
|
1366
|
+
}
|
1367
|
+
else
|
1368
|
+
bytes_transferred = 0;
|
1369
|
+
|
1370
|
+
return true;
|
1371
|
+
}
|
1372
|
+
}
|
1373
|
+
|
1374
|
+
#endif // !defined(BOOST_ASIO_HAS_IOCP)
|
1375
|
+
|
1376
|
+
socket_type socket(int af, int type, int protocol,
|
1377
|
+
boost::system::error_code& ec)
|
1378
|
+
{
|
1379
|
+
clear_last_error();
|
1380
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1381
|
+
socket_type s = error_wrapper(::WSASocketW(af, type, protocol, 0, 0,
|
1382
|
+
WSA_FLAG_OVERLAPPED), ec);
|
1383
|
+
if (s == invalid_socket)
|
1384
|
+
return s;
|
1385
|
+
|
1386
|
+
if (af == BOOST_ASIO_OS_DEF(AF_INET6))
|
1387
|
+
{
|
1388
|
+
// Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to
|
1389
|
+
// false. This will only succeed on Windows Vista and later versions of
|
1390
|
+
// Windows, where a dual-stack IPv4/v6 implementation is available.
|
1391
|
+
DWORD optval = 0;
|
1392
|
+
::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
1393
|
+
reinterpret_cast<const char*>(&optval), sizeof(optval));
|
1394
|
+
}
|
1395
|
+
|
1396
|
+
ec = boost::system::error_code();
|
1397
|
+
|
1398
|
+
return s;
|
1399
|
+
#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
1400
|
+
socket_type s = error_wrapper(::socket(af, type, protocol), ec);
|
1401
|
+
if (s == invalid_socket)
|
1402
|
+
return s;
|
1403
|
+
|
1404
|
+
int optval = 1;
|
1405
|
+
int result = error_wrapper(::setsockopt(s,
|
1406
|
+
SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
|
1407
|
+
if (result != 0)
|
1408
|
+
{
|
1409
|
+
::close(s);
|
1410
|
+
return invalid_socket;
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
return s;
|
1414
|
+
#else
|
1415
|
+
int s = error_wrapper(::socket(af, type, protocol), ec);
|
1416
|
+
if (s >= 0)
|
1417
|
+
ec = boost::system::error_code();
|
1418
|
+
return s;
|
1419
|
+
#endif
|
1420
|
+
}
|
1421
|
+
|
1422
|
+
template <typename SockLenType>
|
1423
|
+
inline int call_setsockopt(SockLenType msghdr::*,
|
1424
|
+
socket_type s, int level, int optname,
|
1425
|
+
const void* optval, std::size_t optlen)
|
1426
|
+
{
|
1427
|
+
return ::setsockopt(s, level, optname,
|
1428
|
+
(const char*)optval, (SockLenType)optlen);
|
1429
|
+
}
|
1430
|
+
|
1431
|
+
int setsockopt(socket_type s, state_type& state, int level, int optname,
|
1432
|
+
const void* optval, std::size_t optlen, boost::system::error_code& ec)
|
1433
|
+
{
|
1434
|
+
if (s == invalid_socket)
|
1435
|
+
{
|
1436
|
+
ec = boost::asio::error::bad_descriptor;
|
1437
|
+
return socket_error_retval;
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
if (level == custom_socket_option_level && optname == always_fail_option)
|
1441
|
+
{
|
1442
|
+
ec = boost::asio::error::invalid_argument;
|
1443
|
+
return socket_error_retval;
|
1444
|
+
}
|
1445
|
+
|
1446
|
+
if (level == custom_socket_option_level
|
1447
|
+
&& optname == enable_connection_aborted_option)
|
1448
|
+
{
|
1449
|
+
if (optlen != sizeof(int))
|
1450
|
+
{
|
1451
|
+
ec = boost::asio::error::invalid_argument;
|
1452
|
+
return socket_error_retval;
|
1453
|
+
}
|
1454
|
+
|
1455
|
+
if (*static_cast<const int*>(optval))
|
1456
|
+
state |= enable_connection_aborted;
|
1457
|
+
else
|
1458
|
+
state &= ~enable_connection_aborted;
|
1459
|
+
ec = boost::system::error_code();
|
1460
|
+
return 0;
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
if (level == SOL_SOCKET && optname == SO_LINGER)
|
1464
|
+
state |= user_set_linger;
|
1465
|
+
|
1466
|
+
#if defined(__BORLANDC__)
|
1467
|
+
// Mysteriously, using the getsockopt and setsockopt functions directly with
|
1468
|
+
// Borland C++ results in incorrect values being set and read. The bug can be
|
1469
|
+
// worked around by using function addresses resolved with GetProcAddress.
|
1470
|
+
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
1471
|
+
{
|
1472
|
+
typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int);
|
1473
|
+
if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt"))
|
1474
|
+
{
|
1475
|
+
clear_last_error();
|
1476
|
+
return error_wrapper(sso(s, level, optname,
|
1477
|
+
reinterpret_cast<const char*>(optval),
|
1478
|
+
static_cast<int>(optlen)), ec);
|
1479
|
+
}
|
1480
|
+
}
|
1481
|
+
ec = boost::asio::error::fault;
|
1482
|
+
return socket_error_retval;
|
1483
|
+
#else // defined(__BORLANDC__)
|
1484
|
+
clear_last_error();
|
1485
|
+
int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
|
1486
|
+
s, level, optname, optval, optlen), ec);
|
1487
|
+
if (result == 0)
|
1488
|
+
{
|
1489
|
+
ec = boost::system::error_code();
|
1490
|
+
|
1491
|
+
#if defined(__MACH__) && defined(__APPLE__) \
|
1492
|
+
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
1493
|
+
// To implement portable behaviour for SO_REUSEADDR with UDP sockets we
|
1494
|
+
// need to also set SO_REUSEPORT on BSD-based platforms.
|
1495
|
+
if ((state & datagram_oriented)
|
1496
|
+
&& level == SOL_SOCKET && optname == SO_REUSEADDR)
|
1497
|
+
{
|
1498
|
+
call_setsockopt(&msghdr::msg_namelen, s,
|
1499
|
+
SOL_SOCKET, SO_REUSEPORT, optval, optlen);
|
1500
|
+
}
|
1501
|
+
#endif
|
1502
|
+
}
|
1503
|
+
|
1504
|
+
return result;
|
1505
|
+
#endif // defined(__BORLANDC__)
|
1506
|
+
}
|
1507
|
+
|
1508
|
+
template <typename SockLenType>
|
1509
|
+
inline int call_getsockopt(SockLenType msghdr::*,
|
1510
|
+
socket_type s, int level, int optname,
|
1511
|
+
void* optval, std::size_t* optlen)
|
1512
|
+
{
|
1513
|
+
SockLenType tmp_optlen = (SockLenType)*optlen;
|
1514
|
+
int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
|
1515
|
+
*optlen = (std::size_t)tmp_optlen;
|
1516
|
+
return result;
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
int getsockopt(socket_type s, state_type state, int level, int optname,
|
1520
|
+
void* optval, size_t* optlen, boost::system::error_code& ec)
|
1521
|
+
{
|
1522
|
+
if (s == invalid_socket)
|
1523
|
+
{
|
1524
|
+
ec = boost::asio::error::bad_descriptor;
|
1525
|
+
return socket_error_retval;
|
1526
|
+
}
|
1527
|
+
|
1528
|
+
if (level == custom_socket_option_level && optname == always_fail_option)
|
1529
|
+
{
|
1530
|
+
ec = boost::asio::error::invalid_argument;
|
1531
|
+
return socket_error_retval;
|
1532
|
+
}
|
1533
|
+
|
1534
|
+
if (level == custom_socket_option_level
|
1535
|
+
&& optname == enable_connection_aborted_option)
|
1536
|
+
{
|
1537
|
+
if (*optlen != sizeof(int))
|
1538
|
+
{
|
1539
|
+
ec = boost::asio::error::invalid_argument;
|
1540
|
+
return socket_error_retval;
|
1541
|
+
}
|
1542
|
+
|
1543
|
+
*static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0;
|
1544
|
+
ec = boost::system::error_code();
|
1545
|
+
return 0;
|
1546
|
+
}
|
1547
|
+
|
1548
|
+
#if defined(__BORLANDC__)
|
1549
|
+
// Mysteriously, using the getsockopt and setsockopt functions directly with
|
1550
|
+
// Borland C++ results in incorrect values being set and read. The bug can be
|
1551
|
+
// worked around by using function addresses resolved with GetProcAddress.
|
1552
|
+
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
1553
|
+
{
|
1554
|
+
typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*);
|
1555
|
+
if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt"))
|
1556
|
+
{
|
1557
|
+
clear_last_error();
|
1558
|
+
int tmp_optlen = static_cast<int>(*optlen);
|
1559
|
+
int result = error_wrapper(gso(s, level, optname,
|
1560
|
+
reinterpret_cast<char*>(optval), &tmp_optlen), ec);
|
1561
|
+
*optlen = static_cast<size_t>(tmp_optlen);
|
1562
|
+
if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
|
1563
|
+
&& ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
|
1564
|
+
{
|
1565
|
+
// Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are
|
1566
|
+
// only supported on Windows Vista and later. To simplify program logic
|
1567
|
+
// we will fake success of getting this option and specify that the
|
1568
|
+
// value is non-zero (i.e. true). This corresponds to the behavior of
|
1569
|
+
// IPv6 sockets on Windows platforms pre-Vista.
|
1570
|
+
*static_cast<DWORD*>(optval) = 1;
|
1571
|
+
ec = boost::system::error_code();
|
1572
|
+
}
|
1573
|
+
return result;
|
1574
|
+
}
|
1575
|
+
}
|
1576
|
+
ec = boost::asio::error::fault;
|
1577
|
+
return socket_error_retval;
|
1578
|
+
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1579
|
+
clear_last_error();
|
1580
|
+
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
|
1581
|
+
s, level, optname, optval, optlen), ec);
|
1582
|
+
if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
|
1583
|
+
&& ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
|
1584
|
+
{
|
1585
|
+
// Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only
|
1586
|
+
// supported on Windows Vista and later. To simplify program logic we will
|
1587
|
+
// fake success of getting this option and specify that the value is
|
1588
|
+
// non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets
|
1589
|
+
// on Windows platforms pre-Vista.
|
1590
|
+
*static_cast<DWORD*>(optval) = 1;
|
1591
|
+
ec = boost::system::error_code();
|
1592
|
+
}
|
1593
|
+
if (result == 0)
|
1594
|
+
ec = boost::system::error_code();
|
1595
|
+
return result;
|
1596
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1597
|
+
clear_last_error();
|
1598
|
+
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
|
1599
|
+
s, level, optname, optval, optlen), ec);
|
1600
|
+
#if defined(__linux__)
|
1601
|
+
if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
|
1602
|
+
&& (optname == SO_SNDBUF || optname == SO_RCVBUF))
|
1603
|
+
{
|
1604
|
+
// On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel
|
1605
|
+
// to set the buffer size to N*2. Linux puts additional stuff into the
|
1606
|
+
// buffers so that only about half is actually available to the application.
|
1607
|
+
// The retrieved value is divided by 2 here to make it appear as though the
|
1608
|
+
// correct value has been set.
|
1609
|
+
*static_cast<int*>(optval) /= 2;
|
1610
|
+
}
|
1611
|
+
#endif // defined(__linux__)
|
1612
|
+
if (result == 0)
|
1613
|
+
ec = boost::system::error_code();
|
1614
|
+
return result;
|
1615
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
template <typename SockLenType>
|
1619
|
+
inline int call_getpeername(SockLenType msghdr::*,
|
1620
|
+
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
|
1621
|
+
{
|
1622
|
+
SockLenType tmp_addrlen = (SockLenType)*addrlen;
|
1623
|
+
int result = ::getpeername(s, addr, &tmp_addrlen);
|
1624
|
+
*addrlen = (std::size_t)tmp_addrlen;
|
1625
|
+
return result;
|
1626
|
+
}
|
1627
|
+
|
1628
|
+
int getpeername(socket_type s, socket_addr_type* addr,
|
1629
|
+
std::size_t* addrlen, bool cached, boost::system::error_code& ec)
|
1630
|
+
{
|
1631
|
+
if (s == invalid_socket)
|
1632
|
+
{
|
1633
|
+
ec = boost::asio::error::bad_descriptor;
|
1634
|
+
return socket_error_retval;
|
1635
|
+
}
|
1636
|
+
|
1637
|
+
#if defined(BOOST_ASIO_WINDOWS) && !defined(BOOST_ASIO_WINDOWS_APP) \
|
1638
|
+
|| defined(__CYGWIN__)
|
1639
|
+
if (cached)
|
1640
|
+
{
|
1641
|
+
// Check if socket is still connected.
|
1642
|
+
DWORD connect_time = 0;
|
1643
|
+
size_t connect_time_len = sizeof(connect_time);
|
1644
|
+
if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_CONNECT_TIME,
|
1645
|
+
&connect_time, &connect_time_len, ec) == socket_error_retval)
|
1646
|
+
{
|
1647
|
+
return socket_error_retval;
|
1648
|
+
}
|
1649
|
+
if (connect_time == 0xFFFFFFFF)
|
1650
|
+
{
|
1651
|
+
ec = boost::asio::error::not_connected;
|
1652
|
+
return socket_error_retval;
|
1653
|
+
}
|
1654
|
+
|
1655
|
+
// The cached value is still valid.
|
1656
|
+
ec = boost::system::error_code();
|
1657
|
+
return 0;
|
1658
|
+
}
|
1659
|
+
#else // defined(BOOST_ASIO_WINDOWS) && !defined(BOOST_ASIO_WINDOWS_APP)
|
1660
|
+
// || defined(__CYGWIN__)
|
1661
|
+
(void)cached;
|
1662
|
+
#endif // defined(BOOST_ASIO_WINDOWS) && !defined(BOOST_ASIO_WINDOWS_APP)
|
1663
|
+
// || defined(__CYGWIN__)
|
1664
|
+
|
1665
|
+
clear_last_error();
|
1666
|
+
int result = error_wrapper(call_getpeername(
|
1667
|
+
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
1668
|
+
if (result == 0)
|
1669
|
+
ec = boost::system::error_code();
|
1670
|
+
return result;
|
1671
|
+
}
|
1672
|
+
|
1673
|
+
template <typename SockLenType>
|
1674
|
+
inline int call_getsockname(SockLenType msghdr::*,
|
1675
|
+
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
|
1676
|
+
{
|
1677
|
+
SockLenType tmp_addrlen = (SockLenType)*addrlen;
|
1678
|
+
int result = ::getsockname(s, addr, &tmp_addrlen);
|
1679
|
+
*addrlen = (std::size_t)tmp_addrlen;
|
1680
|
+
return result;
|
1681
|
+
}
|
1682
|
+
|
1683
|
+
int getsockname(socket_type s, socket_addr_type* addr,
|
1684
|
+
std::size_t* addrlen, boost::system::error_code& ec)
|
1685
|
+
{
|
1686
|
+
if (s == invalid_socket)
|
1687
|
+
{
|
1688
|
+
ec = boost::asio::error::bad_descriptor;
|
1689
|
+
return socket_error_retval;
|
1690
|
+
}
|
1691
|
+
|
1692
|
+
clear_last_error();
|
1693
|
+
int result = error_wrapper(call_getsockname(
|
1694
|
+
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
1695
|
+
if (result == 0)
|
1696
|
+
ec = boost::system::error_code();
|
1697
|
+
return result;
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
int ioctl(socket_type s, state_type& state, int cmd,
|
1701
|
+
ioctl_arg_type* arg, boost::system::error_code& ec)
|
1702
|
+
{
|
1703
|
+
if (s == invalid_socket)
|
1704
|
+
{
|
1705
|
+
ec = boost::asio::error::bad_descriptor;
|
1706
|
+
return socket_error_retval;
|
1707
|
+
}
|
1708
|
+
|
1709
|
+
clear_last_error();
|
1710
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1711
|
+
int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
|
1712
|
+
#elif defined(__MACH__) && defined(__APPLE__) \
|
1713
|
+
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
1714
|
+
int result = error_wrapper(::ioctl(s,
|
1715
|
+
static_cast<unsigned int>(cmd), arg), ec);
|
1716
|
+
#else
|
1717
|
+
int result = error_wrapper(::ioctl(s, cmd, arg), ec);
|
1718
|
+
#endif
|
1719
|
+
if (result >= 0)
|
1720
|
+
{
|
1721
|
+
ec = boost::system::error_code();
|
1722
|
+
|
1723
|
+
// When updating the non-blocking mode we always perform the ioctl syscall,
|
1724
|
+
// even if the flags would otherwise indicate that the socket is already in
|
1725
|
+
// the correct state. This ensures that the underlying socket is put into
|
1726
|
+
// the state that has been requested by the user. If the ioctl syscall was
|
1727
|
+
// successful then we need to update the flags to match.
|
1728
|
+
if (cmd == static_cast<int>(FIONBIO))
|
1729
|
+
{
|
1730
|
+
if (*arg)
|
1731
|
+
{
|
1732
|
+
state |= user_set_non_blocking;
|
1733
|
+
}
|
1734
|
+
else
|
1735
|
+
{
|
1736
|
+
// Clearing the non-blocking mode always overrides any internally-set
|
1737
|
+
// non-blocking flag. Any subsequent asynchronous operations will need
|
1738
|
+
// to re-enable non-blocking I/O.
|
1739
|
+
state &= ~(user_set_non_blocking | internal_non_blocking);
|
1740
|
+
}
|
1741
|
+
}
|
1742
|
+
}
|
1743
|
+
|
1744
|
+
return result;
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
int select(int nfds, fd_set* readfds, fd_set* writefds,
|
1748
|
+
fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec)
|
1749
|
+
{
|
1750
|
+
clear_last_error();
|
1751
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1752
|
+
if (!readfds && !writefds && !exceptfds && timeout)
|
1753
|
+
{
|
1754
|
+
DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
1755
|
+
if (milliseconds == 0)
|
1756
|
+
milliseconds = 1; // Force context switch.
|
1757
|
+
::Sleep(milliseconds);
|
1758
|
+
ec = boost::system::error_code();
|
1759
|
+
return 0;
|
1760
|
+
}
|
1761
|
+
|
1762
|
+
// The select() call allows timeout values measured in microseconds, but the
|
1763
|
+
// system clock (as wrapped by boost::posix_time::microsec_clock) typically
|
1764
|
+
// has a resolution of 10 milliseconds. This can lead to a spinning select
|
1765
|
+
// reactor, meaning increased CPU usage, when waiting for the earliest
|
1766
|
+
// scheduled timeout if it's less than 10 milliseconds away. To avoid a tight
|
1767
|
+
// spin we'll use a minimum timeout of 1 millisecond.
|
1768
|
+
if (timeout && timeout->tv_sec == 0
|
1769
|
+
&& timeout->tv_usec > 0 && timeout->tv_usec < 1000)
|
1770
|
+
timeout->tv_usec = 1000;
|
1771
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1772
|
+
|
1773
|
+
#if defined(__hpux) && defined(__SELECT)
|
1774
|
+
timespec ts;
|
1775
|
+
ts.tv_sec = timeout ? timeout->tv_sec : 0;
|
1776
|
+
ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
|
1777
|
+
return error_wrapper(::pselect(nfds, readfds,
|
1778
|
+
writefds, exceptfds, timeout ? &ts : 0, 0), ec);
|
1779
|
+
#else
|
1780
|
+
int result = error_wrapper(::select(nfds, readfds,
|
1781
|
+
writefds, exceptfds, timeout), ec);
|
1782
|
+
if (result >= 0)
|
1783
|
+
ec = boost::system::error_code();
|
1784
|
+
return result;
|
1785
|
+
#endif
|
1786
|
+
}
|
1787
|
+
|
1788
|
+
int poll_read(socket_type s, state_type state, boost::system::error_code& ec)
|
1789
|
+
{
|
1790
|
+
if (s == invalid_socket)
|
1791
|
+
{
|
1792
|
+
ec = boost::asio::error::bad_descriptor;
|
1793
|
+
return socket_error_retval;
|
1794
|
+
}
|
1795
|
+
|
1796
|
+
#if defined(BOOST_ASIO_WINDOWS) \
|
1797
|
+
|| defined(__CYGWIN__) \
|
1798
|
+
|| defined(__SYMBIAN32__)
|
1799
|
+
fd_set fds;
|
1800
|
+
FD_ZERO(&fds);
|
1801
|
+
FD_SET(s, &fds);
|
1802
|
+
timeval zero_timeout;
|
1803
|
+
zero_timeout.tv_sec = 0;
|
1804
|
+
zero_timeout.tv_usec = 0;
|
1805
|
+
timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0;
|
1806
|
+
clear_last_error();
|
1807
|
+
int result = error_wrapper(::select(s + 1, &fds, 0, 0, timeout), ec);
|
1808
|
+
#else // defined(BOOST_ASIO_WINDOWS)
|
1809
|
+
// || defined(__CYGWIN__)
|
1810
|
+
// || defined(__SYMBIAN32__)
|
1811
|
+
pollfd fds;
|
1812
|
+
fds.fd = s;
|
1813
|
+
fds.events = POLLIN;
|
1814
|
+
fds.revents = 0;
|
1815
|
+
int timeout = (state & user_set_non_blocking) ? 0 : -1;
|
1816
|
+
clear_last_error();
|
1817
|
+
int result = error_wrapper(::poll(&fds, 1, timeout), ec);
|
1818
|
+
#endif // defined(BOOST_ASIO_WINDOWS)
|
1819
|
+
// || defined(__CYGWIN__)
|
1820
|
+
// || defined(__SYMBIAN32__)
|
1821
|
+
if (result == 0)
|
1822
|
+
ec = (state & user_set_non_blocking)
|
1823
|
+
? boost::asio::error::would_block : boost::system::error_code();
|
1824
|
+
else if (result > 0)
|
1825
|
+
ec = boost::system::error_code();
|
1826
|
+
return result;
|
1827
|
+
}
|
1828
|
+
|
1829
|
+
int poll_write(socket_type s, state_type state, boost::system::error_code& ec)
|
1830
|
+
{
|
1831
|
+
if (s == invalid_socket)
|
1832
|
+
{
|
1833
|
+
ec = boost::asio::error::bad_descriptor;
|
1834
|
+
return socket_error_retval;
|
1835
|
+
}
|
1836
|
+
|
1837
|
+
#if defined(BOOST_ASIO_WINDOWS) \
|
1838
|
+
|| defined(__CYGWIN__) \
|
1839
|
+
|| defined(__SYMBIAN32__)
|
1840
|
+
fd_set fds;
|
1841
|
+
FD_ZERO(&fds);
|
1842
|
+
FD_SET(s, &fds);
|
1843
|
+
timeval zero_timeout;
|
1844
|
+
zero_timeout.tv_sec = 0;
|
1845
|
+
zero_timeout.tv_usec = 0;
|
1846
|
+
timeval* timeout = (state & user_set_non_blocking) ? &zero_timeout : 0;
|
1847
|
+
clear_last_error();
|
1848
|
+
int result = error_wrapper(::select(s + 1, 0, &fds, 0, timeout), ec);
|
1849
|
+
#else // defined(BOOST_ASIO_WINDOWS)
|
1850
|
+
// || defined(__CYGWIN__)
|
1851
|
+
// || defined(__SYMBIAN32__)
|
1852
|
+
pollfd fds;
|
1853
|
+
fds.fd = s;
|
1854
|
+
fds.events = POLLOUT;
|
1855
|
+
fds.revents = 0;
|
1856
|
+
int timeout = (state & user_set_non_blocking) ? 0 : -1;
|
1857
|
+
clear_last_error();
|
1858
|
+
int result = error_wrapper(::poll(&fds, 1, timeout), ec);
|
1859
|
+
#endif // defined(BOOST_ASIO_WINDOWS)
|
1860
|
+
// || defined(__CYGWIN__)
|
1861
|
+
// || defined(__SYMBIAN32__)
|
1862
|
+
if (result == 0)
|
1863
|
+
ec = (state & user_set_non_blocking)
|
1864
|
+
? boost::asio::error::would_block : boost::system::error_code();
|
1865
|
+
else if (result > 0)
|
1866
|
+
ec = boost::system::error_code();
|
1867
|
+
return result;
|
1868
|
+
}
|
1869
|
+
|
1870
|
+
int poll_connect(socket_type s, boost::system::error_code& ec)
|
1871
|
+
{
|
1872
|
+
if (s == invalid_socket)
|
1873
|
+
{
|
1874
|
+
ec = boost::asio::error::bad_descriptor;
|
1875
|
+
return socket_error_retval;
|
1876
|
+
}
|
1877
|
+
|
1878
|
+
#if defined(BOOST_ASIO_WINDOWS) \
|
1879
|
+
|| defined(__CYGWIN__) \
|
1880
|
+
|| defined(__SYMBIAN32__)
|
1881
|
+
fd_set write_fds;
|
1882
|
+
FD_ZERO(&write_fds);
|
1883
|
+
FD_SET(s, &write_fds);
|
1884
|
+
fd_set except_fds;
|
1885
|
+
FD_ZERO(&except_fds);
|
1886
|
+
FD_SET(s, &except_fds);
|
1887
|
+
clear_last_error();
|
1888
|
+
int result = error_wrapper(::select(
|
1889
|
+
s + 1, 0, &write_fds, &except_fds, 0), ec);
|
1890
|
+
if (result >= 0)
|
1891
|
+
ec = boost::system::error_code();
|
1892
|
+
return result;
|
1893
|
+
#else // defined(BOOST_ASIO_WINDOWS)
|
1894
|
+
// || defined(__CYGWIN__)
|
1895
|
+
// || defined(__SYMBIAN32__)
|
1896
|
+
pollfd fds;
|
1897
|
+
fds.fd = s;
|
1898
|
+
fds.events = POLLOUT;
|
1899
|
+
fds.revents = 0;
|
1900
|
+
clear_last_error();
|
1901
|
+
int result = error_wrapper(::poll(&fds, 1, -1), ec);
|
1902
|
+
if (result >= 0)
|
1903
|
+
ec = boost::system::error_code();
|
1904
|
+
return result;
|
1905
|
+
#endif // defined(BOOST_ASIO_WINDOWS)
|
1906
|
+
// || defined(__CYGWIN__)
|
1907
|
+
// || defined(__SYMBIAN32__)
|
1908
|
+
}
|
1909
|
+
|
1910
|
+
#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
1911
|
+
|
1912
|
+
const char* inet_ntop(int af, const void* src, char* dest, size_t length,
|
1913
|
+
unsigned long scope_id, boost::system::error_code& ec)
|
1914
|
+
{
|
1915
|
+
clear_last_error();
|
1916
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
1917
|
+
using namespace std; // For sprintf.
|
1918
|
+
const unsigned char* bytes = static_cast<const unsigned char*>(src);
|
1919
|
+
if (af == BOOST_ASIO_OS_DEF(AF_INET))
|
1920
|
+
{
|
1921
|
+
sprintf_s(dest, length, "%u.%u.%u.%u",
|
1922
|
+
bytes[0], bytes[1], bytes[2], bytes[3]);
|
1923
|
+
return dest;
|
1924
|
+
}
|
1925
|
+
else if (af == BOOST_ASIO_OS_DEF(AF_INET6))
|
1926
|
+
{
|
1927
|
+
size_t n = 0, b = 0, z = 0;
|
1928
|
+
while (n < length && b < 16)
|
1929
|
+
{
|
1930
|
+
if (bytes[b] == 0 && bytes[b + 1] == 0 && z == 0)
|
1931
|
+
{
|
1932
|
+
do b += 2; while (b < 16 && bytes[b] == 0 && bytes[b + 1] == 0);
|
1933
|
+
n += sprintf_s(dest + n, length - n, ":%s", b < 16 ? "" : ":"), ++z;
|
1934
|
+
}
|
1935
|
+
else
|
1936
|
+
{
|
1937
|
+
n += sprintf_s(dest + n, length - n, "%s%x", b ? ":" : "",
|
1938
|
+
(static_cast<u_long_type>(bytes[b]) << 8) | bytes[b + 1]);
|
1939
|
+
b += 2;
|
1940
|
+
}
|
1941
|
+
}
|
1942
|
+
if (scope_id)
|
1943
|
+
n += sprintf_s(dest + n, length - n, "%%%lu", scope_id);
|
1944
|
+
return dest;
|
1945
|
+
}
|
1946
|
+
else
|
1947
|
+
{
|
1948
|
+
ec = boost::asio::error::address_family_not_supported;
|
1949
|
+
return 0;
|
1950
|
+
}
|
1951
|
+
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
1952
|
+
using namespace std; // For memcpy.
|
1953
|
+
|
1954
|
+
if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6))
|
1955
|
+
{
|
1956
|
+
ec = boost::asio::error::address_family_not_supported;
|
1957
|
+
return 0;
|
1958
|
+
}
|
1959
|
+
|
1960
|
+
union
|
1961
|
+
{
|
1962
|
+
socket_addr_type base;
|
1963
|
+
sockaddr_storage_type storage;
|
1964
|
+
sockaddr_in4_type v4;
|
1965
|
+
sockaddr_in6_type v6;
|
1966
|
+
} address;
|
1967
|
+
DWORD address_length;
|
1968
|
+
if (af == BOOST_ASIO_OS_DEF(AF_INET))
|
1969
|
+
{
|
1970
|
+
address_length = sizeof(sockaddr_in4_type);
|
1971
|
+
address.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET);
|
1972
|
+
address.v4.sin_port = 0;
|
1973
|
+
memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type));
|
1974
|
+
}
|
1975
|
+
else // AF_INET6
|
1976
|
+
{
|
1977
|
+
address_length = sizeof(sockaddr_in6_type);
|
1978
|
+
address.v6.sin6_family = BOOST_ASIO_OS_DEF(AF_INET6);
|
1979
|
+
address.v6.sin6_port = 0;
|
1980
|
+
address.v6.sin6_flowinfo = 0;
|
1981
|
+
address.v6.sin6_scope_id = scope_id;
|
1982
|
+
memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type));
|
1983
|
+
}
|
1984
|
+
|
1985
|
+
DWORD string_length = static_cast<DWORD>(length);
|
1986
|
+
#if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800))
|
1987
|
+
LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
|
1988
|
+
int result = error_wrapper(::WSAAddressToStringW(&address.base,
|
1989
|
+
address_length, 0, string_buffer, &string_length), ec);
|
1990
|
+
::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1,
|
1991
|
+
dest, static_cast<int>(length), 0, 0);
|
1992
|
+
#else
|
1993
|
+
int result = error_wrapper(::WSAAddressToStringA(
|
1994
|
+
&address.base, address_length, 0, dest, &string_length), ec);
|
1995
|
+
#endif
|
1996
|
+
|
1997
|
+
// Windows may set error code on success.
|
1998
|
+
if (result != socket_error_retval)
|
1999
|
+
ec = boost::system::error_code();
|
2000
|
+
|
2001
|
+
// Windows may not set an error code on failure.
|
2002
|
+
else if (result == socket_error_retval && !ec)
|
2003
|
+
ec = boost::asio::error::invalid_argument;
|
2004
|
+
|
2005
|
+
return result == socket_error_retval ? 0 : dest;
|
2006
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2007
|
+
const char* result = error_wrapper(::inet_ntop(
|
2008
|
+
af, src, dest, static_cast<int>(length)), ec);
|
2009
|
+
if (result == 0 && !ec)
|
2010
|
+
ec = boost::asio::error::invalid_argument;
|
2011
|
+
if (result != 0 && af == BOOST_ASIO_OS_DEF(AF_INET6) && scope_id != 0)
|
2012
|
+
{
|
2013
|
+
using namespace std; // For strcat and sprintf.
|
2014
|
+
char if_name[IF_NAMESIZE + 1] = "%";
|
2015
|
+
const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);
|
2016
|
+
bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
|
2017
|
+
&& ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
|
2018
|
+
bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff)
|
2019
|
+
&& ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
|
2020
|
+
if ((!is_link_local && !is_multicast_link_local)
|
2021
|
+
|| if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0)
|
2022
|
+
sprintf(if_name + 1, "%lu", scope_id);
|
2023
|
+
strcat(dest, if_name);
|
2024
|
+
}
|
2025
|
+
return result;
|
2026
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2027
|
+
}
|
2028
|
+
|
2029
|
+
int inet_pton(int af, const char* src, void* dest,
|
2030
|
+
unsigned long* scope_id, boost::system::error_code& ec)
|
2031
|
+
{
|
2032
|
+
clear_last_error();
|
2033
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
2034
|
+
using namespace std; // For sscanf.
|
2035
|
+
unsigned char* bytes = static_cast<unsigned char*>(dest);
|
2036
|
+
if (af == BOOST_ASIO_OS_DEF(AF_INET))
|
2037
|
+
{
|
2038
|
+
unsigned int b0, b1, b2, b3;
|
2039
|
+
if (sscanf_s(src, "%u.%u.%u.%u", &b0, &b1, &b2, &b3) != 4)
|
2040
|
+
{
|
2041
|
+
ec = boost::asio::error::invalid_argument;
|
2042
|
+
return -1;
|
2043
|
+
}
|
2044
|
+
if (b0 > 255 || b1 > 255 || b2 > 255 || b3 > 255)
|
2045
|
+
{
|
2046
|
+
ec = boost::asio::error::invalid_argument;
|
2047
|
+
return -1;
|
2048
|
+
}
|
2049
|
+
bytes[0] = static_cast<unsigned char>(b0);
|
2050
|
+
bytes[1] = static_cast<unsigned char>(b1);
|
2051
|
+
bytes[2] = static_cast<unsigned char>(b2);
|
2052
|
+
bytes[3] = static_cast<unsigned char>(b3);
|
2053
|
+
ec = boost::system::error_code();
|
2054
|
+
return 1;
|
2055
|
+
}
|
2056
|
+
else if (af == BOOST_ASIO_OS_DEF(AF_INET6))
|
2057
|
+
{
|
2058
|
+
unsigned char* bytes = static_cast<unsigned char*>(dest);
|
2059
|
+
std::memset(bytes, 0, 16);
|
2060
|
+
unsigned char back_bytes[16] = { 0 };
|
2061
|
+
int num_front_bytes = 0, num_back_bytes = 0;
|
2062
|
+
const char* p = src;
|
2063
|
+
|
2064
|
+
enum { fword, fcolon, bword, scope, done } state = fword;
|
2065
|
+
unsigned long current_word = 0;
|
2066
|
+
while (state != done)
|
2067
|
+
{
|
2068
|
+
if (current_word > 0xFFFF)
|
2069
|
+
{
|
2070
|
+
ec = boost::asio::error::invalid_argument;
|
2071
|
+
return -1;
|
2072
|
+
}
|
2073
|
+
|
2074
|
+
switch (state)
|
2075
|
+
{
|
2076
|
+
case fword:
|
2077
|
+
if (*p >= '0' && *p <= '9')
|
2078
|
+
current_word = current_word * 16 + *p++ - '0';
|
2079
|
+
else if (*p >= 'a' && *p <= 'f')
|
2080
|
+
current_word = current_word * 16 + *p++ - 'a' + 10;
|
2081
|
+
else if (*p >= 'A' && *p <= 'F')
|
2082
|
+
current_word = current_word * 16 + *p++ - 'A' + 10;
|
2083
|
+
else
|
2084
|
+
{
|
2085
|
+
if (num_front_bytes == 16)
|
2086
|
+
{
|
2087
|
+
ec = boost::asio::error::invalid_argument;
|
2088
|
+
return -1;
|
2089
|
+
}
|
2090
|
+
|
2091
|
+
bytes[num_front_bytes++] = (current_word >> 8) & 0xFF;
|
2092
|
+
bytes[num_front_bytes++] = current_word & 0xFF;
|
2093
|
+
current_word = 0;
|
2094
|
+
|
2095
|
+
if (*p == ':')
|
2096
|
+
state = fcolon, ++p;
|
2097
|
+
else if (*p == '%')
|
2098
|
+
state = scope, ++p;
|
2099
|
+
else if (*p == 0)
|
2100
|
+
state = done;
|
2101
|
+
else
|
2102
|
+
{
|
2103
|
+
ec = boost::asio::error::invalid_argument;
|
2104
|
+
return -1;
|
2105
|
+
}
|
2106
|
+
}
|
2107
|
+
break;
|
2108
|
+
|
2109
|
+
case fcolon:
|
2110
|
+
if (*p == ':')
|
2111
|
+
state = bword, ++p;
|
2112
|
+
else
|
2113
|
+
state = fword;
|
2114
|
+
break;
|
2115
|
+
|
2116
|
+
case bword:
|
2117
|
+
if (*p >= '0' && *p <= '9')
|
2118
|
+
current_word = current_word * 16 + *p++ - '0';
|
2119
|
+
else if (*p >= 'a' && *p <= 'f')
|
2120
|
+
current_word = current_word * 16 + *p++ - 'a' + 10;
|
2121
|
+
else if (*p >= 'A' && *p <= 'F')
|
2122
|
+
current_word = current_word * 16 + *p++ - 'A' + 10;
|
2123
|
+
else
|
2124
|
+
{
|
2125
|
+
if (num_front_bytes + num_back_bytes == 16)
|
2126
|
+
{
|
2127
|
+
ec = boost::asio::error::invalid_argument;
|
2128
|
+
return -1;
|
2129
|
+
}
|
2130
|
+
|
2131
|
+
back_bytes[num_back_bytes++] = (current_word >> 8) & 0xFF;
|
2132
|
+
back_bytes[num_back_bytes++] = current_word & 0xFF;
|
2133
|
+
current_word = 0;
|
2134
|
+
|
2135
|
+
if (*p == ':')
|
2136
|
+
state = bword, ++p;
|
2137
|
+
else if (*p == '%')
|
2138
|
+
state = scope, ++p;
|
2139
|
+
else if (*p == 0)
|
2140
|
+
state = done;
|
2141
|
+
else
|
2142
|
+
{
|
2143
|
+
ec = boost::asio::error::invalid_argument;
|
2144
|
+
return -1;
|
2145
|
+
}
|
2146
|
+
}
|
2147
|
+
break;
|
2148
|
+
|
2149
|
+
case scope:
|
2150
|
+
if (*p >= '0' && *p <= '9')
|
2151
|
+
current_word = current_word * 10 + *p++ - '0';
|
2152
|
+
else if (*p == 0)
|
2153
|
+
*scope_id = current_word, state = done;
|
2154
|
+
else
|
2155
|
+
{
|
2156
|
+
ec = boost::asio::error::invalid_argument;
|
2157
|
+
return -1;
|
2158
|
+
}
|
2159
|
+
break;
|
2160
|
+
|
2161
|
+
default:
|
2162
|
+
break;
|
2163
|
+
}
|
2164
|
+
}
|
2165
|
+
|
2166
|
+
for (int i = 0; i < num_back_bytes; ++i)
|
2167
|
+
bytes[16 - num_back_bytes + i] = back_bytes[i];
|
2168
|
+
|
2169
|
+
ec = boost::system::error_code();
|
2170
|
+
return 1;
|
2171
|
+
}
|
2172
|
+
else
|
2173
|
+
{
|
2174
|
+
ec = boost::asio::error::address_family_not_supported;
|
2175
|
+
return -1;
|
2176
|
+
}
|
2177
|
+
#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2178
|
+
using namespace std; // For memcpy and strcmp.
|
2179
|
+
|
2180
|
+
if (af != BOOST_ASIO_OS_DEF(AF_INET) && af != BOOST_ASIO_OS_DEF(AF_INET6))
|
2181
|
+
{
|
2182
|
+
ec = boost::asio::error::address_family_not_supported;
|
2183
|
+
return -1;
|
2184
|
+
}
|
2185
|
+
|
2186
|
+
union
|
2187
|
+
{
|
2188
|
+
socket_addr_type base;
|
2189
|
+
sockaddr_storage_type storage;
|
2190
|
+
sockaddr_in4_type v4;
|
2191
|
+
sockaddr_in6_type v6;
|
2192
|
+
} address;
|
2193
|
+
int address_length = sizeof(sockaddr_storage_type);
|
2194
|
+
#if defined(BOOST_NO_ANSI_APIS) || (defined(_MSC_VER) && (_MSC_VER >= 1800))
|
2195
|
+
int num_wide_chars = static_cast<int>(strlen(src)) + 1;
|
2196
|
+
LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));
|
2197
|
+
::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);
|
2198
|
+
int result = error_wrapper(::WSAStringToAddressW(
|
2199
|
+
wide_buffer, af, 0, &address.base, &address_length), ec);
|
2200
|
+
#else
|
2201
|
+
int result = error_wrapper(::WSAStringToAddressA(
|
2202
|
+
const_cast<char*>(src), af, 0, &address.base, &address_length), ec);
|
2203
|
+
#endif
|
2204
|
+
|
2205
|
+
if (af == BOOST_ASIO_OS_DEF(AF_INET))
|
2206
|
+
{
|
2207
|
+
if (result != socket_error_retval)
|
2208
|
+
{
|
2209
|
+
memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type));
|
2210
|
+
ec = boost::system::error_code();
|
2211
|
+
}
|
2212
|
+
else if (strcmp(src, "255.255.255.255") == 0)
|
2213
|
+
{
|
2214
|
+
static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE;
|
2215
|
+
ec = boost::system::error_code();
|
2216
|
+
}
|
2217
|
+
}
|
2218
|
+
else // AF_INET6
|
2219
|
+
{
|
2220
|
+
if (result != socket_error_retval)
|
2221
|
+
{
|
2222
|
+
memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type));
|
2223
|
+
if (scope_id)
|
2224
|
+
*scope_id = address.v6.sin6_scope_id;
|
2225
|
+
ec = boost::system::error_code();
|
2226
|
+
}
|
2227
|
+
}
|
2228
|
+
|
2229
|
+
// Windows may not set an error code on failure.
|
2230
|
+
if (result == socket_error_retval && !ec)
|
2231
|
+
ec = boost::asio::error::invalid_argument;
|
2232
|
+
|
2233
|
+
if (result != socket_error_retval)
|
2234
|
+
ec = boost::system::error_code();
|
2235
|
+
|
2236
|
+
return result == socket_error_retval ? -1 : 1;
|
2237
|
+
#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2238
|
+
using namespace std; // For strchr, memcpy and atoi.
|
2239
|
+
|
2240
|
+
// On some platforms, inet_pton fails if an address string contains a scope
|
2241
|
+
// id. Detect and remove the scope id before passing the string to inet_pton.
|
2242
|
+
const bool is_v6 = (af == BOOST_ASIO_OS_DEF(AF_INET6));
|
2243
|
+
const char* if_name = is_v6 ? strchr(src, '%') : 0;
|
2244
|
+
char src_buf[max_addr_v6_str_len + 1];
|
2245
|
+
const char* src_ptr = src;
|
2246
|
+
if (if_name != 0)
|
2247
|
+
{
|
2248
|
+
if (if_name - src > max_addr_v6_str_len)
|
2249
|
+
{
|
2250
|
+
ec = boost::asio::error::invalid_argument;
|
2251
|
+
return 0;
|
2252
|
+
}
|
2253
|
+
memcpy(src_buf, src, if_name - src);
|
2254
|
+
src_buf[if_name - src] = 0;
|
2255
|
+
src_ptr = src_buf;
|
2256
|
+
}
|
2257
|
+
|
2258
|
+
int result = error_wrapper(::inet_pton(af, src_ptr, dest), ec);
|
2259
|
+
if (result <= 0 && !ec)
|
2260
|
+
ec = boost::asio::error::invalid_argument;
|
2261
|
+
if (result > 0 && is_v6 && scope_id)
|
2262
|
+
{
|
2263
|
+
using namespace std; // For strchr and atoi.
|
2264
|
+
*scope_id = 0;
|
2265
|
+
if (if_name != 0)
|
2266
|
+
{
|
2267
|
+
in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);
|
2268
|
+
bool is_link_local = ((ipv6_address->s6_addr[0] == 0xfe)
|
2269
|
+
&& ((ipv6_address->s6_addr[1] & 0xc0) == 0x80));
|
2270
|
+
bool is_multicast_link_local = ((ipv6_address->s6_addr[0] == 0xff)
|
2271
|
+
&& ((ipv6_address->s6_addr[1] & 0x0f) == 0x02));
|
2272
|
+
if (is_link_local || is_multicast_link_local)
|
2273
|
+
*scope_id = if_nametoindex(if_name + 1);
|
2274
|
+
if (*scope_id == 0)
|
2275
|
+
*scope_id = atoi(if_name + 1);
|
2276
|
+
}
|
2277
|
+
}
|
2278
|
+
return result;
|
2279
|
+
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2280
|
+
}
|
2281
|
+
|
2282
|
+
int gethostname(char* name, int namelen, boost::system::error_code& ec)
|
2283
|
+
{
|
2284
|
+
clear_last_error();
|
2285
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
2286
|
+
try
|
2287
|
+
{
|
2288
|
+
using namespace Windows::Foundation::Collections;
|
2289
|
+
using namespace Windows::Networking;
|
2290
|
+
using namespace Windows::Networking::Connectivity;
|
2291
|
+
IVectorView<HostName^>^ hostnames = NetworkInformation::GetHostNames();
|
2292
|
+
for (unsigned i = 0; i < hostnames->Size; ++i)
|
2293
|
+
{
|
2294
|
+
HostName^ hostname = hostnames->GetAt(i);
|
2295
|
+
if (hostname->Type == HostNameType::DomainName)
|
2296
|
+
{
|
2297
|
+
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
2298
|
+
std::string raw_name = converter.to_bytes(hostname->RawName->Data());
|
2299
|
+
if (namelen > 0 && raw_name.size() < static_cast<std::size_t>(namelen))
|
2300
|
+
{
|
2301
|
+
strcpy_s(name, namelen, raw_name.c_str());
|
2302
|
+
return 0;
|
2303
|
+
}
|
2304
|
+
}
|
2305
|
+
}
|
2306
|
+
return -1;
|
2307
|
+
}
|
2308
|
+
catch (Platform::Exception^ e)
|
2309
|
+
{
|
2310
|
+
ec = boost::system::error_code(e->HResult,
|
2311
|
+
boost::system::system_category());
|
2312
|
+
return -1;
|
2313
|
+
}
|
2314
|
+
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
2315
|
+
int result = error_wrapper(::gethostname(name, namelen), ec);
|
2316
|
+
# if defined(BOOST_ASIO_WINDOWS)
|
2317
|
+
if (result == 0)
|
2318
|
+
ec = boost::system::error_code();
|
2319
|
+
# endif // defined(BOOST_ASIO_WINDOWS)
|
2320
|
+
return result;
|
2321
|
+
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
2322
|
+
}
|
2323
|
+
|
2324
|
+
#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
2325
|
+
|
2326
|
+
#if !defined(BOOST_ASIO_HAS_GETADDRINFO)
|
2327
|
+
|
2328
|
+
// The following functions are only needed for emulation of getaddrinfo and
|
2329
|
+
// getnameinfo.
|
2330
|
+
|
2331
|
+
inline boost::system::error_code translate_netdb_error(int error)
|
2332
|
+
{
|
2333
|
+
switch (error)
|
2334
|
+
{
|
2335
|
+
case 0:
|
2336
|
+
return boost::system::error_code();
|
2337
|
+
case HOST_NOT_FOUND:
|
2338
|
+
return boost::asio::error::host_not_found;
|
2339
|
+
case TRY_AGAIN:
|
2340
|
+
return boost::asio::error::host_not_found_try_again;
|
2341
|
+
case NO_RECOVERY:
|
2342
|
+
return boost::asio::error::no_recovery;
|
2343
|
+
case NO_DATA:
|
2344
|
+
return boost::asio::error::no_data;
|
2345
|
+
default:
|
2346
|
+
BOOST_ASIO_ASSERT(false);
|
2347
|
+
return boost::asio::error::invalid_argument;
|
2348
|
+
}
|
2349
|
+
}
|
2350
|
+
|
2351
|
+
inline hostent* gethostbyaddr(const char* addr, int length, int af,
|
2352
|
+
hostent* result, char* buffer, int buflength, boost::system::error_code& ec)
|
2353
|
+
{
|
2354
|
+
clear_last_error();
|
2355
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2356
|
+
(void)(buffer);
|
2357
|
+
(void)(buflength);
|
2358
|
+
hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
|
2359
|
+
if (!retval)
|
2360
|
+
return 0;
|
2361
|
+
ec = boost::system::error_code();
|
2362
|
+
*result = *retval;
|
2363
|
+
return retval;
|
2364
|
+
#elif defined(__sun) || defined(__QNX__)
|
2365
|
+
int error = 0;
|
2366
|
+
hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result,
|
2367
|
+
buffer, buflength, &error), ec);
|
2368
|
+
if (error)
|
2369
|
+
ec = translate_netdb_error(error);
|
2370
|
+
return retval;
|
2371
|
+
#elif defined(__MACH__) && defined(__APPLE__)
|
2372
|
+
(void)(buffer);
|
2373
|
+
(void)(buflength);
|
2374
|
+
int error = 0;
|
2375
|
+
hostent* retval = error_wrapper(::getipnodebyaddr(
|
2376
|
+
addr, length, af, &error), ec);
|
2377
|
+
if (error)
|
2378
|
+
ec = translate_netdb_error(error);
|
2379
|
+
if (!retval)
|
2380
|
+
return 0;
|
2381
|
+
*result = *retval;
|
2382
|
+
return retval;
|
2383
|
+
#else
|
2384
|
+
hostent* retval = 0;
|
2385
|
+
int error = 0;
|
2386
|
+
error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer,
|
2387
|
+
buflength, &retval, &error), ec);
|
2388
|
+
if (error)
|
2389
|
+
ec = translate_netdb_error(error);
|
2390
|
+
return retval;
|
2391
|
+
#endif
|
2392
|
+
}
|
2393
|
+
|
2394
|
+
inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
|
2395
|
+
char* buffer, int buflength, int ai_flags, boost::system::error_code& ec)
|
2396
|
+
{
|
2397
|
+
clear_last_error();
|
2398
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
2399
|
+
(void)(buffer);
|
2400
|
+
(void)(buflength);
|
2401
|
+
(void)(ai_flags);
|
2402
|
+
if (af != BOOST_ASIO_OS_DEF(AF_INET))
|
2403
|
+
{
|
2404
|
+
ec = boost::asio::error::address_family_not_supported;
|
2405
|
+
return 0;
|
2406
|
+
}
|
2407
|
+
hostent* retval = error_wrapper(::gethostbyname(name), ec);
|
2408
|
+
if (!retval)
|
2409
|
+
return 0;
|
2410
|
+
ec = boost::system::error_code();
|
2411
|
+
*result = *retval;
|
2412
|
+
return result;
|
2413
|
+
#elif defined(__sun) || defined(__QNX__)
|
2414
|
+
(void)(ai_flags);
|
2415
|
+
if (af != BOOST_ASIO_OS_DEF(AF_INET))
|
2416
|
+
{
|
2417
|
+
ec = boost::asio::error::address_family_not_supported;
|
2418
|
+
return 0;
|
2419
|
+
}
|
2420
|
+
int error = 0;
|
2421
|
+
hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer,
|
2422
|
+
buflength, &error), ec);
|
2423
|
+
if (error)
|
2424
|
+
ec = translate_netdb_error(error);
|
2425
|
+
return retval;
|
2426
|
+
#elif defined(__MACH__) && defined(__APPLE__)
|
2427
|
+
(void)(buffer);
|
2428
|
+
(void)(buflength);
|
2429
|
+
int error = 0;
|
2430
|
+
hostent* retval = error_wrapper(::getipnodebyname(
|
2431
|
+
name, af, ai_flags, &error), ec);
|
2432
|
+
if (error)
|
2433
|
+
ec = translate_netdb_error(error);
|
2434
|
+
if (!retval)
|
2435
|
+
return 0;
|
2436
|
+
*result = *retval;
|
2437
|
+
return retval;
|
2438
|
+
#else
|
2439
|
+
(void)(ai_flags);
|
2440
|
+
if (af != BOOST_ASIO_OS_DEF(AF_INET))
|
2441
|
+
{
|
2442
|
+
ec = boost::asio::error::address_family_not_supported;
|
2443
|
+
return 0;
|
2444
|
+
}
|
2445
|
+
hostent* retval = 0;
|
2446
|
+
int error = 0;
|
2447
|
+
error_wrapper(::gethostbyname_r(name, result,
|
2448
|
+
buffer, buflength, &retval, &error), ec);
|
2449
|
+
if (error)
|
2450
|
+
ec = translate_netdb_error(error);
|
2451
|
+
return retval;
|
2452
|
+
#endif
|
2453
|
+
}
|
2454
|
+
|
2455
|
+
inline void freehostent(hostent* h)
|
2456
|
+
{
|
2457
|
+
#if defined(__MACH__) && defined(__APPLE__)
|
2458
|
+
if (h)
|
2459
|
+
::freehostent(h);
|
2460
|
+
#else
|
2461
|
+
(void)(h);
|
2462
|
+
#endif
|
2463
|
+
}
|
2464
|
+
|
2465
|
+
// Emulation of getaddrinfo based on implementation in:
|
2466
|
+
// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998.
|
2467
|
+
|
2468
|
+
struct gai_search
|
2469
|
+
{
|
2470
|
+
const char* host;
|
2471
|
+
int family;
|
2472
|
+
};
|
2473
|
+
|
2474
|
+
inline int gai_nsearch(const char* host,
|
2475
|
+
const addrinfo_type* hints, gai_search (&search)[2])
|
2476
|
+
{
|
2477
|
+
int search_count = 0;
|
2478
|
+
if (host == 0 || host[0] == '\0')
|
2479
|
+
{
|
2480
|
+
if (hints->ai_flags & AI_PASSIVE)
|
2481
|
+
{
|
2482
|
+
// No host and AI_PASSIVE implies wildcard bind.
|
2483
|
+
switch (hints->ai_family)
|
2484
|
+
{
|
2485
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
2486
|
+
search[search_count].host = "0.0.0.0";
|
2487
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
|
2488
|
+
++search_count;
|
2489
|
+
break;
|
2490
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
2491
|
+
search[search_count].host = "0::0";
|
2492
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2493
|
+
++search_count;
|
2494
|
+
break;
|
2495
|
+
case BOOST_ASIO_OS_DEF(AF_UNSPEC):
|
2496
|
+
search[search_count].host = "0::0";
|
2497
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2498
|
+
++search_count;
|
2499
|
+
search[search_count].host = "0.0.0.0";
|
2500
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
|
2501
|
+
++search_count;
|
2502
|
+
break;
|
2503
|
+
default:
|
2504
|
+
break;
|
2505
|
+
}
|
2506
|
+
}
|
2507
|
+
else
|
2508
|
+
{
|
2509
|
+
// No host and not AI_PASSIVE means connect to local host.
|
2510
|
+
switch (hints->ai_family)
|
2511
|
+
{
|
2512
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
2513
|
+
search[search_count].host = "localhost";
|
2514
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
|
2515
|
+
++search_count;
|
2516
|
+
break;
|
2517
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
2518
|
+
search[search_count].host = "localhost";
|
2519
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2520
|
+
++search_count;
|
2521
|
+
break;
|
2522
|
+
case BOOST_ASIO_OS_DEF(AF_UNSPEC):
|
2523
|
+
search[search_count].host = "localhost";
|
2524
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2525
|
+
++search_count;
|
2526
|
+
search[search_count].host = "localhost";
|
2527
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
|
2528
|
+
++search_count;
|
2529
|
+
break;
|
2530
|
+
default:
|
2531
|
+
break;
|
2532
|
+
}
|
2533
|
+
}
|
2534
|
+
}
|
2535
|
+
else
|
2536
|
+
{
|
2537
|
+
// Host is specified.
|
2538
|
+
switch (hints->ai_family)
|
2539
|
+
{
|
2540
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
2541
|
+
search[search_count].host = host;
|
2542
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
|
2543
|
+
++search_count;
|
2544
|
+
break;
|
2545
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
2546
|
+
search[search_count].host = host;
|
2547
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2548
|
+
++search_count;
|
2549
|
+
break;
|
2550
|
+
case BOOST_ASIO_OS_DEF(AF_UNSPEC):
|
2551
|
+
search[search_count].host = host;
|
2552
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2553
|
+
++search_count;
|
2554
|
+
search[search_count].host = host;
|
2555
|
+
search[search_count].family = BOOST_ASIO_OS_DEF(AF_INET);
|
2556
|
+
++search_count;
|
2557
|
+
break;
|
2558
|
+
default:
|
2559
|
+
break;
|
2560
|
+
}
|
2561
|
+
}
|
2562
|
+
return search_count;
|
2563
|
+
}
|
2564
|
+
|
2565
|
+
template <typename T>
|
2566
|
+
inline T* gai_alloc(std::size_t size = sizeof(T))
|
2567
|
+
{
|
2568
|
+
using namespace std;
|
2569
|
+
T* p = static_cast<T*>(::operator new(size, std::nothrow));
|
2570
|
+
if (p)
|
2571
|
+
memset(p, 0, size);
|
2572
|
+
return p;
|
2573
|
+
}
|
2574
|
+
|
2575
|
+
inline void gai_free(void* p)
|
2576
|
+
{
|
2577
|
+
::operator delete(p);
|
2578
|
+
}
|
2579
|
+
|
2580
|
+
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
|
2581
|
+
{
|
2582
|
+
using namespace std;
|
2583
|
+
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
|
2584
|
+
strcpy_s(target, max_size, source);
|
2585
|
+
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
2586
|
+
*target = 0;
|
2587
|
+
if (max_size > 0)
|
2588
|
+
strncat(target, source, max_size - 1);
|
2589
|
+
#endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
2590
|
+
}
|
2591
|
+
|
2592
|
+
enum { gai_clone_flag = 1 << 30 };
|
2593
|
+
|
2594
|
+
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
|
2595
|
+
const void* addr, int family)
|
2596
|
+
{
|
2597
|
+
using namespace std;
|
2598
|
+
|
2599
|
+
addrinfo_type* ai = gai_alloc<addrinfo_type>();
|
2600
|
+
if (ai == 0)
|
2601
|
+
return EAI_MEMORY;
|
2602
|
+
|
2603
|
+
ai->ai_next = 0;
|
2604
|
+
**next = ai;
|
2605
|
+
*next = &ai->ai_next;
|
2606
|
+
|
2607
|
+
ai->ai_canonname = 0;
|
2608
|
+
ai->ai_socktype = hints->ai_socktype;
|
2609
|
+
if (ai->ai_socktype == 0)
|
2610
|
+
ai->ai_flags |= gai_clone_flag;
|
2611
|
+
ai->ai_protocol = hints->ai_protocol;
|
2612
|
+
ai->ai_family = family;
|
2613
|
+
|
2614
|
+
switch (ai->ai_family)
|
2615
|
+
{
|
2616
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
2617
|
+
{
|
2618
|
+
sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>();
|
2619
|
+
if (sinptr == 0)
|
2620
|
+
return EAI_MEMORY;
|
2621
|
+
sinptr->sin_family = BOOST_ASIO_OS_DEF(AF_INET);
|
2622
|
+
memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type));
|
2623
|
+
ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr);
|
2624
|
+
ai->ai_addrlen = sizeof(sockaddr_in4_type);
|
2625
|
+
break;
|
2626
|
+
}
|
2627
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
2628
|
+
{
|
2629
|
+
sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>();
|
2630
|
+
if (sin6ptr == 0)
|
2631
|
+
return EAI_MEMORY;
|
2632
|
+
sin6ptr->sin6_family = BOOST_ASIO_OS_DEF(AF_INET6);
|
2633
|
+
memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type));
|
2634
|
+
ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr);
|
2635
|
+
ai->ai_addrlen = sizeof(sockaddr_in6_type);
|
2636
|
+
break;
|
2637
|
+
}
|
2638
|
+
default:
|
2639
|
+
break;
|
2640
|
+
}
|
2641
|
+
|
2642
|
+
return 0;
|
2643
|
+
}
|
2644
|
+
|
2645
|
+
inline addrinfo_type* gai_clone(addrinfo_type* ai)
|
2646
|
+
{
|
2647
|
+
using namespace std;
|
2648
|
+
|
2649
|
+
addrinfo_type* new_ai = gai_alloc<addrinfo_type>();
|
2650
|
+
if (new_ai == 0)
|
2651
|
+
return new_ai;
|
2652
|
+
|
2653
|
+
new_ai->ai_next = ai->ai_next;
|
2654
|
+
ai->ai_next = new_ai;
|
2655
|
+
|
2656
|
+
new_ai->ai_flags = 0;
|
2657
|
+
new_ai->ai_family = ai->ai_family;
|
2658
|
+
new_ai->ai_socktype = ai->ai_socktype;
|
2659
|
+
new_ai->ai_protocol = ai->ai_protocol;
|
2660
|
+
new_ai->ai_canonname = 0;
|
2661
|
+
new_ai->ai_addrlen = ai->ai_addrlen;
|
2662
|
+
new_ai->ai_addr = gai_alloc<sockaddr>(ai->ai_addrlen);
|
2663
|
+
memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen);
|
2664
|
+
|
2665
|
+
return new_ai;
|
2666
|
+
}
|
2667
|
+
|
2668
|
+
inline int gai_port(addrinfo_type* aihead, int port, int socktype)
|
2669
|
+
{
|
2670
|
+
int num_found = 0;
|
2671
|
+
|
2672
|
+
for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next)
|
2673
|
+
{
|
2674
|
+
if (ai->ai_flags & gai_clone_flag)
|
2675
|
+
{
|
2676
|
+
if (ai->ai_socktype != 0)
|
2677
|
+
{
|
2678
|
+
ai = gai_clone(ai);
|
2679
|
+
if (ai == 0)
|
2680
|
+
return -1;
|
2681
|
+
// ai now points to newly cloned entry.
|
2682
|
+
}
|
2683
|
+
}
|
2684
|
+
else if (ai->ai_socktype != socktype)
|
2685
|
+
{
|
2686
|
+
// Ignore if mismatch on socket type.
|
2687
|
+
continue;
|
2688
|
+
}
|
2689
|
+
|
2690
|
+
ai->ai_socktype = socktype;
|
2691
|
+
|
2692
|
+
switch (ai->ai_family)
|
2693
|
+
{
|
2694
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
2695
|
+
{
|
2696
|
+
sockaddr_in4_type* sinptr =
|
2697
|
+
reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr);
|
2698
|
+
sinptr->sin_port = port;
|
2699
|
+
++num_found;
|
2700
|
+
break;
|
2701
|
+
}
|
2702
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
2703
|
+
{
|
2704
|
+
sockaddr_in6_type* sin6ptr =
|
2705
|
+
reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr);
|
2706
|
+
sin6ptr->sin6_port = port;
|
2707
|
+
++num_found;
|
2708
|
+
break;
|
2709
|
+
}
|
2710
|
+
default:
|
2711
|
+
break;
|
2712
|
+
}
|
2713
|
+
}
|
2714
|
+
|
2715
|
+
return num_found;
|
2716
|
+
}
|
2717
|
+
|
2718
|
+
inline int gai_serv(addrinfo_type* aihead,
|
2719
|
+
const addrinfo_type* hints, const char* serv)
|
2720
|
+
{
|
2721
|
+
using namespace std;
|
2722
|
+
|
2723
|
+
int num_found = 0;
|
2724
|
+
|
2725
|
+
if (
|
2726
|
+
#if defined(AI_NUMERICSERV)
|
2727
|
+
(hints->ai_flags & AI_NUMERICSERV) ||
|
2728
|
+
#endif
|
2729
|
+
isdigit(static_cast<unsigned char>(serv[0])))
|
2730
|
+
{
|
2731
|
+
int port = htons(atoi(serv));
|
2732
|
+
if (hints->ai_socktype)
|
2733
|
+
{
|
2734
|
+
// Caller specifies socket type.
|
2735
|
+
int rc = gai_port(aihead, port, hints->ai_socktype);
|
2736
|
+
if (rc < 0)
|
2737
|
+
return EAI_MEMORY;
|
2738
|
+
num_found += rc;
|
2739
|
+
}
|
2740
|
+
else
|
2741
|
+
{
|
2742
|
+
// Caller does not specify socket type.
|
2743
|
+
int rc = gai_port(aihead, port, SOCK_STREAM);
|
2744
|
+
if (rc < 0)
|
2745
|
+
return EAI_MEMORY;
|
2746
|
+
num_found += rc;
|
2747
|
+
rc = gai_port(aihead, port, SOCK_DGRAM);
|
2748
|
+
if (rc < 0)
|
2749
|
+
return EAI_MEMORY;
|
2750
|
+
num_found += rc;
|
2751
|
+
}
|
2752
|
+
}
|
2753
|
+
else
|
2754
|
+
{
|
2755
|
+
// Try service name with TCP first, then UDP.
|
2756
|
+
if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM)
|
2757
|
+
{
|
2758
|
+
servent* sptr = getservbyname(serv, "tcp");
|
2759
|
+
if (sptr != 0)
|
2760
|
+
{
|
2761
|
+
int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM);
|
2762
|
+
if (rc < 0)
|
2763
|
+
return EAI_MEMORY;
|
2764
|
+
num_found += rc;
|
2765
|
+
}
|
2766
|
+
}
|
2767
|
+
if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM)
|
2768
|
+
{
|
2769
|
+
servent* sptr = getservbyname(serv, "udp");
|
2770
|
+
if (sptr != 0)
|
2771
|
+
{
|
2772
|
+
int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM);
|
2773
|
+
if (rc < 0)
|
2774
|
+
return EAI_MEMORY;
|
2775
|
+
num_found += rc;
|
2776
|
+
}
|
2777
|
+
}
|
2778
|
+
}
|
2779
|
+
|
2780
|
+
if (num_found == 0)
|
2781
|
+
{
|
2782
|
+
if (hints->ai_socktype == 0)
|
2783
|
+
{
|
2784
|
+
// All calls to getservbyname() failed.
|
2785
|
+
return EAI_NONAME;
|
2786
|
+
}
|
2787
|
+
else
|
2788
|
+
{
|
2789
|
+
// Service not supported for socket type.
|
2790
|
+
return EAI_SERVICE;
|
2791
|
+
}
|
2792
|
+
}
|
2793
|
+
|
2794
|
+
return 0;
|
2795
|
+
}
|
2796
|
+
|
2797
|
+
inline int gai_echeck(const char* host, const char* service,
|
2798
|
+
int flags, int family, int socktype, int protocol)
|
2799
|
+
{
|
2800
|
+
(void)(flags);
|
2801
|
+
(void)(protocol);
|
2802
|
+
|
2803
|
+
// Host or service must be specified.
|
2804
|
+
if (host == 0 || host[0] == '\0')
|
2805
|
+
if (service == 0 || service[0] == '\0')
|
2806
|
+
return EAI_NONAME;
|
2807
|
+
|
2808
|
+
// Check combination of family and socket type.
|
2809
|
+
switch (family)
|
2810
|
+
{
|
2811
|
+
case BOOST_ASIO_OS_DEF(AF_UNSPEC):
|
2812
|
+
break;
|
2813
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
2814
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
2815
|
+
if (service != 0 && service[0] != '\0')
|
2816
|
+
if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
|
2817
|
+
return EAI_SOCKTYPE;
|
2818
|
+
break;
|
2819
|
+
default:
|
2820
|
+
return EAI_FAMILY;
|
2821
|
+
}
|
2822
|
+
|
2823
|
+
return 0;
|
2824
|
+
}
|
2825
|
+
|
2826
|
+
inline void freeaddrinfo_emulation(addrinfo_type* aihead)
|
2827
|
+
{
|
2828
|
+
addrinfo_type* ai = aihead;
|
2829
|
+
while (ai)
|
2830
|
+
{
|
2831
|
+
gai_free(ai->ai_addr);
|
2832
|
+
gai_free(ai->ai_canonname);
|
2833
|
+
addrinfo_type* ainext = ai->ai_next;
|
2834
|
+
gai_free(ai);
|
2835
|
+
ai = ainext;
|
2836
|
+
}
|
2837
|
+
}
|
2838
|
+
|
2839
|
+
inline int getaddrinfo_emulation(const char* host, const char* service,
|
2840
|
+
const addrinfo_type* hintsp, addrinfo_type** result)
|
2841
|
+
{
|
2842
|
+
// Set up linked list of addrinfo structures.
|
2843
|
+
addrinfo_type* aihead = 0;
|
2844
|
+
addrinfo_type** ainext = &aihead;
|
2845
|
+
char* canon = 0;
|
2846
|
+
|
2847
|
+
// Supply default hints if not specified by caller.
|
2848
|
+
addrinfo_type hints = addrinfo_type();
|
2849
|
+
hints.ai_family = BOOST_ASIO_OS_DEF(AF_UNSPEC);
|
2850
|
+
if (hintsp)
|
2851
|
+
hints = *hintsp;
|
2852
|
+
|
2853
|
+
// If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED
|
2854
|
+
// and AI_ALL flags.
|
2855
|
+
#if defined(AI_V4MAPPED)
|
2856
|
+
if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6))
|
2857
|
+
hints.ai_flags &= ~AI_V4MAPPED;
|
2858
|
+
#endif
|
2859
|
+
#if defined(AI_ALL)
|
2860
|
+
if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6))
|
2861
|
+
hints.ai_flags &= ~AI_ALL;
|
2862
|
+
#endif
|
2863
|
+
|
2864
|
+
// Basic error checking.
|
2865
|
+
int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family,
|
2866
|
+
hints.ai_socktype, hints.ai_protocol);
|
2867
|
+
if (rc != 0)
|
2868
|
+
{
|
2869
|
+
freeaddrinfo_emulation(aihead);
|
2870
|
+
return rc;
|
2871
|
+
}
|
2872
|
+
|
2873
|
+
gai_search search[2];
|
2874
|
+
int search_count = gai_nsearch(host, &hints, search);
|
2875
|
+
for (gai_search* sptr = search; sptr < search + search_count; ++sptr)
|
2876
|
+
{
|
2877
|
+
// Check for IPv4 dotted decimal string.
|
2878
|
+
in4_addr_type inaddr;
|
2879
|
+
boost::system::error_code ec;
|
2880
|
+
if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET),
|
2881
|
+
sptr->host, &inaddr, 0, ec) == 1)
|
2882
|
+
{
|
2883
|
+
if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC)
|
2884
|
+
&& hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET))
|
2885
|
+
{
|
2886
|
+
freeaddrinfo_emulation(aihead);
|
2887
|
+
gai_free(canon);
|
2888
|
+
return EAI_FAMILY;
|
2889
|
+
}
|
2890
|
+
if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET))
|
2891
|
+
{
|
2892
|
+
rc = gai_aistruct(&ainext, &hints, &inaddr, BOOST_ASIO_OS_DEF(AF_INET));
|
2893
|
+
if (rc != 0)
|
2894
|
+
{
|
2895
|
+
freeaddrinfo_emulation(aihead);
|
2896
|
+
gai_free(canon);
|
2897
|
+
return rc;
|
2898
|
+
}
|
2899
|
+
}
|
2900
|
+
continue;
|
2901
|
+
}
|
2902
|
+
|
2903
|
+
// Check for IPv6 hex string.
|
2904
|
+
in6_addr_type in6addr;
|
2905
|
+
if (socket_ops::inet_pton(BOOST_ASIO_OS_DEF(AF_INET6),
|
2906
|
+
sptr->host, &in6addr, 0, ec) == 1)
|
2907
|
+
{
|
2908
|
+
if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC)
|
2909
|
+
&& hints.ai_family != BOOST_ASIO_OS_DEF(AF_INET6))
|
2910
|
+
{
|
2911
|
+
freeaddrinfo_emulation(aihead);
|
2912
|
+
gai_free(canon);
|
2913
|
+
return EAI_FAMILY;
|
2914
|
+
}
|
2915
|
+
if (sptr->family == BOOST_ASIO_OS_DEF(AF_INET6))
|
2916
|
+
{
|
2917
|
+
rc = gai_aistruct(&ainext, &hints, &in6addr,
|
2918
|
+
BOOST_ASIO_OS_DEF(AF_INET6));
|
2919
|
+
if (rc != 0)
|
2920
|
+
{
|
2921
|
+
freeaddrinfo_emulation(aihead);
|
2922
|
+
gai_free(canon);
|
2923
|
+
return rc;
|
2924
|
+
}
|
2925
|
+
}
|
2926
|
+
continue;
|
2927
|
+
}
|
2928
|
+
|
2929
|
+
// Look up hostname.
|
2930
|
+
hostent hent;
|
2931
|
+
char hbuf[8192] = "";
|
2932
|
+
hostent* hptr = socket_ops::gethostbyname(sptr->host,
|
2933
|
+
sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec);
|
2934
|
+
if (hptr == 0)
|
2935
|
+
{
|
2936
|
+
if (search_count == 2)
|
2937
|
+
{
|
2938
|
+
// Failure is OK if there are multiple searches.
|
2939
|
+
continue;
|
2940
|
+
}
|
2941
|
+
freeaddrinfo_emulation(aihead);
|
2942
|
+
gai_free(canon);
|
2943
|
+
if (ec == boost::asio::error::host_not_found)
|
2944
|
+
return EAI_NONAME;
|
2945
|
+
if (ec == boost::asio::error::host_not_found_try_again)
|
2946
|
+
return EAI_AGAIN;
|
2947
|
+
if (ec == boost::asio::error::no_recovery)
|
2948
|
+
return EAI_FAIL;
|
2949
|
+
if (ec == boost::asio::error::no_data)
|
2950
|
+
return EAI_NONAME;
|
2951
|
+
return EAI_NONAME;
|
2952
|
+
}
|
2953
|
+
|
2954
|
+
// Check for address family mismatch if one was specified.
|
2955
|
+
if (hints.ai_family != BOOST_ASIO_OS_DEF(AF_UNSPEC)
|
2956
|
+
&& hints.ai_family != hptr->h_addrtype)
|
2957
|
+
{
|
2958
|
+
freeaddrinfo_emulation(aihead);
|
2959
|
+
gai_free(canon);
|
2960
|
+
socket_ops::freehostent(hptr);
|
2961
|
+
return EAI_FAMILY;
|
2962
|
+
}
|
2963
|
+
|
2964
|
+
// Save canonical name first time.
|
2965
|
+
if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
|
2966
|
+
&& (hints.ai_flags & AI_CANONNAME) && canon == 0)
|
2967
|
+
{
|
2968
|
+
std::size_t canon_len = strlen(hptr->h_name) + 1;
|
2969
|
+
canon = gai_alloc<char>(canon_len);
|
2970
|
+
if (canon == 0)
|
2971
|
+
{
|
2972
|
+
freeaddrinfo_emulation(aihead);
|
2973
|
+
socket_ops::freehostent(hptr);
|
2974
|
+
return EAI_MEMORY;
|
2975
|
+
}
|
2976
|
+
gai_strcpy(canon, hptr->h_name, canon_len);
|
2977
|
+
}
|
2978
|
+
|
2979
|
+
// Create an addrinfo structure for each returned address.
|
2980
|
+
for (char** ap = hptr->h_addr_list; *ap; ++ap)
|
2981
|
+
{
|
2982
|
+
rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype);
|
2983
|
+
if (rc != 0)
|
2984
|
+
{
|
2985
|
+
freeaddrinfo_emulation(aihead);
|
2986
|
+
gai_free(canon);
|
2987
|
+
socket_ops::freehostent(hptr);
|
2988
|
+
return EAI_FAMILY;
|
2989
|
+
}
|
2990
|
+
}
|
2991
|
+
|
2992
|
+
socket_ops::freehostent(hptr);
|
2993
|
+
}
|
2994
|
+
|
2995
|
+
// Check if we found anything.
|
2996
|
+
if (aihead == 0)
|
2997
|
+
{
|
2998
|
+
gai_free(canon);
|
2999
|
+
return EAI_NONAME;
|
3000
|
+
}
|
3001
|
+
|
3002
|
+
// Return canonical name in first entry.
|
3003
|
+
if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME))
|
3004
|
+
{
|
3005
|
+
if (canon)
|
3006
|
+
{
|
3007
|
+
aihead->ai_canonname = canon;
|
3008
|
+
canon = 0;
|
3009
|
+
}
|
3010
|
+
else
|
3011
|
+
{
|
3012
|
+
std::size_t canonname_len = strlen(search[0].host) + 1;
|
3013
|
+
aihead->ai_canonname = gai_alloc<char>(canonname_len);
|
3014
|
+
if (aihead->ai_canonname == 0)
|
3015
|
+
{
|
3016
|
+
freeaddrinfo_emulation(aihead);
|
3017
|
+
return EAI_MEMORY;
|
3018
|
+
}
|
3019
|
+
gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
|
3020
|
+
}
|
3021
|
+
}
|
3022
|
+
gai_free(canon);
|
3023
|
+
|
3024
|
+
// Process the service name.
|
3025
|
+
if (service != 0 && service[0] != '\0')
|
3026
|
+
{
|
3027
|
+
rc = gai_serv(aihead, &hints, service);
|
3028
|
+
if (rc != 0)
|
3029
|
+
{
|
3030
|
+
freeaddrinfo_emulation(aihead);
|
3031
|
+
return rc;
|
3032
|
+
}
|
3033
|
+
}
|
3034
|
+
|
3035
|
+
// Return result to caller.
|
3036
|
+
*result = aihead;
|
3037
|
+
return 0;
|
3038
|
+
}
|
3039
|
+
|
3040
|
+
inline boost::system::error_code getnameinfo_emulation(
|
3041
|
+
const socket_addr_type* sa, std::size_t salen, char* host,
|
3042
|
+
std::size_t hostlen, char* serv, std::size_t servlen, int flags,
|
3043
|
+
boost::system::error_code& ec)
|
3044
|
+
{
|
3045
|
+
using namespace std;
|
3046
|
+
|
3047
|
+
const char* addr;
|
3048
|
+
size_t addr_len;
|
3049
|
+
unsigned short port;
|
3050
|
+
switch (sa->sa_family)
|
3051
|
+
{
|
3052
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
3053
|
+
if (salen != sizeof(sockaddr_in4_type))
|
3054
|
+
{
|
3055
|
+
return ec = boost::asio::error::invalid_argument;
|
3056
|
+
}
|
3057
|
+
addr = reinterpret_cast<const char*>(
|
3058
|
+
&reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr);
|
3059
|
+
addr_len = sizeof(in4_addr_type);
|
3060
|
+
port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port;
|
3061
|
+
break;
|
3062
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
3063
|
+
if (salen != sizeof(sockaddr_in6_type))
|
3064
|
+
{
|
3065
|
+
return ec = boost::asio::error::invalid_argument;
|
3066
|
+
}
|
3067
|
+
addr = reinterpret_cast<const char*>(
|
3068
|
+
&reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr);
|
3069
|
+
addr_len = sizeof(in6_addr_type);
|
3070
|
+
port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port;
|
3071
|
+
break;
|
3072
|
+
default:
|
3073
|
+
return ec = boost::asio::error::address_family_not_supported;
|
3074
|
+
}
|
3075
|
+
|
3076
|
+
if (host && hostlen > 0)
|
3077
|
+
{
|
3078
|
+
if (flags & NI_NUMERICHOST)
|
3079
|
+
{
|
3080
|
+
if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0)
|
3081
|
+
{
|
3082
|
+
return ec;
|
3083
|
+
}
|
3084
|
+
}
|
3085
|
+
else
|
3086
|
+
{
|
3087
|
+
hostent hent;
|
3088
|
+
char hbuf[8192] = "";
|
3089
|
+
hostent* hptr = socket_ops::gethostbyaddr(addr,
|
3090
|
+
static_cast<int>(addr_len), sa->sa_family,
|
3091
|
+
&hent, hbuf, sizeof(hbuf), ec);
|
3092
|
+
if (hptr && hptr->h_name && hptr->h_name[0] != '\0')
|
3093
|
+
{
|
3094
|
+
if (flags & NI_NOFQDN)
|
3095
|
+
{
|
3096
|
+
char* dot = strchr(hptr->h_name, '.');
|
3097
|
+
if (dot)
|
3098
|
+
{
|
3099
|
+
*dot = 0;
|
3100
|
+
}
|
3101
|
+
}
|
3102
|
+
gai_strcpy(host, hptr->h_name, hostlen);
|
3103
|
+
socket_ops::freehostent(hptr);
|
3104
|
+
}
|
3105
|
+
else
|
3106
|
+
{
|
3107
|
+
socket_ops::freehostent(hptr);
|
3108
|
+
if (flags & NI_NAMEREQD)
|
3109
|
+
{
|
3110
|
+
return ec = boost::asio::error::host_not_found;
|
3111
|
+
}
|
3112
|
+
if (socket_ops::inet_ntop(sa->sa_family,
|
3113
|
+
addr, host, hostlen, 0, ec) == 0)
|
3114
|
+
{
|
3115
|
+
return ec;
|
3116
|
+
}
|
3117
|
+
}
|
3118
|
+
}
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
if (serv && servlen > 0)
|
3122
|
+
{
|
3123
|
+
if (flags & NI_NUMERICSERV)
|
3124
|
+
{
|
3125
|
+
if (servlen < 6)
|
3126
|
+
{
|
3127
|
+
return ec = boost::asio::error::no_buffer_space;
|
3128
|
+
}
|
3129
|
+
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
|
3130
|
+
sprintf_s(serv, servlen, "%u", ntohs(port));
|
3131
|
+
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
3132
|
+
sprintf(serv, "%u", ntohs(port));
|
3133
|
+
#endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
3134
|
+
}
|
3135
|
+
else
|
3136
|
+
{
|
3137
|
+
#if defined(BOOST_ASIO_HAS_PTHREADS)
|
3138
|
+
static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
3139
|
+
::pthread_mutex_lock(&mutex);
|
3140
|
+
#endif // defined(BOOST_ASIO_HAS_PTHREADS)
|
3141
|
+
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
|
3142
|
+
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
|
3143
|
+
{
|
3144
|
+
gai_strcpy(serv, sptr->s_name, servlen);
|
3145
|
+
}
|
3146
|
+
else
|
3147
|
+
{
|
3148
|
+
if (servlen < 6)
|
3149
|
+
{
|
3150
|
+
return ec = boost::asio::error::no_buffer_space;
|
3151
|
+
}
|
3152
|
+
#if defined(BOOST_ASIO_HAS_SECURE_RTL)
|
3153
|
+
sprintf_s(serv, servlen, "%u", ntohs(port));
|
3154
|
+
#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
3155
|
+
sprintf(serv, "%u", ntohs(port));
|
3156
|
+
#endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
|
3157
|
+
}
|
3158
|
+
#if defined(BOOST_ASIO_HAS_PTHREADS)
|
3159
|
+
::pthread_mutex_unlock(&mutex);
|
3160
|
+
#endif // defined(BOOST_ASIO_HAS_PTHREADS)
|
3161
|
+
}
|
3162
|
+
}
|
3163
|
+
|
3164
|
+
ec = boost::system::error_code();
|
3165
|
+
return ec;
|
3166
|
+
}
|
3167
|
+
|
3168
|
+
#endif // !defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3169
|
+
|
3170
|
+
inline boost::system::error_code translate_addrinfo_error(int error)
|
3171
|
+
{
|
3172
|
+
switch (error)
|
3173
|
+
{
|
3174
|
+
case 0:
|
3175
|
+
return boost::system::error_code();
|
3176
|
+
case EAI_AGAIN:
|
3177
|
+
return boost::asio::error::host_not_found_try_again;
|
3178
|
+
case EAI_BADFLAGS:
|
3179
|
+
return boost::asio::error::invalid_argument;
|
3180
|
+
case EAI_FAIL:
|
3181
|
+
return boost::asio::error::no_recovery;
|
3182
|
+
case EAI_FAMILY:
|
3183
|
+
return boost::asio::error::address_family_not_supported;
|
3184
|
+
case EAI_MEMORY:
|
3185
|
+
return boost::asio::error::no_memory;
|
3186
|
+
case EAI_NONAME:
|
3187
|
+
#if defined(EAI_ADDRFAMILY)
|
3188
|
+
case EAI_ADDRFAMILY:
|
3189
|
+
#endif
|
3190
|
+
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
3191
|
+
case EAI_NODATA:
|
3192
|
+
#endif
|
3193
|
+
return boost::asio::error::host_not_found;
|
3194
|
+
case EAI_SERVICE:
|
3195
|
+
return boost::asio::error::service_not_found;
|
3196
|
+
case EAI_SOCKTYPE:
|
3197
|
+
return boost::asio::error::socket_type_not_supported;
|
3198
|
+
default: // Possibly the non-portable EAI_SYSTEM.
|
3199
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
3200
|
+
return boost::system::error_code(
|
3201
|
+
WSAGetLastError(), boost::asio::error::get_system_category());
|
3202
|
+
#else
|
3203
|
+
return boost::system::error_code(
|
3204
|
+
errno, boost::asio::error::get_system_category());
|
3205
|
+
#endif
|
3206
|
+
}
|
3207
|
+
}
|
3208
|
+
|
3209
|
+
boost::system::error_code getaddrinfo(const char* host,
|
3210
|
+
const char* service, const addrinfo_type& hints,
|
3211
|
+
addrinfo_type** result, boost::system::error_code& ec)
|
3212
|
+
{
|
3213
|
+
host = (host && *host) ? host : 0;
|
3214
|
+
service = (service && *service) ? service : 0;
|
3215
|
+
clear_last_error();
|
3216
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
3217
|
+
# if defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3218
|
+
// Building for Windows XP, Windows Server 2003, or later.
|
3219
|
+
int error = ::getaddrinfo(host, service, &hints, result);
|
3220
|
+
return ec = translate_addrinfo_error(error);
|
3221
|
+
# else
|
3222
|
+
// Building for Windows 2000 or earlier.
|
3223
|
+
typedef int (WSAAPI *gai_t)(const char*,
|
3224
|
+
const char*, const addrinfo_type*, addrinfo_type**);
|
3225
|
+
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
3226
|
+
{
|
3227
|
+
if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo"))
|
3228
|
+
{
|
3229
|
+
int error = gai(host, service, &hints, result);
|
3230
|
+
return ec = translate_addrinfo_error(error);
|
3231
|
+
}
|
3232
|
+
}
|
3233
|
+
int error = getaddrinfo_emulation(host, service, &hints, result);
|
3234
|
+
return ec = translate_addrinfo_error(error);
|
3235
|
+
# endif
|
3236
|
+
#elif !defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3237
|
+
int error = getaddrinfo_emulation(host, service, &hints, result);
|
3238
|
+
return ec = translate_addrinfo_error(error);
|
3239
|
+
#else
|
3240
|
+
int error = ::getaddrinfo(host, service, &hints, result);
|
3241
|
+
#if defined(__MACH__) && defined(__APPLE__)
|
3242
|
+
using namespace std; // For isdigit and atoi.
|
3243
|
+
if (error == 0 && service && isdigit(static_cast<unsigned char>(service[0])))
|
3244
|
+
{
|
3245
|
+
u_short_type port = host_to_network_short(atoi(service));
|
3246
|
+
for (addrinfo_type* ai = *result; ai; ai = ai->ai_next)
|
3247
|
+
{
|
3248
|
+
switch (ai->ai_family)
|
3249
|
+
{
|
3250
|
+
case BOOST_ASIO_OS_DEF(AF_INET):
|
3251
|
+
{
|
3252
|
+
sockaddr_in4_type* sinptr =
|
3253
|
+
reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr);
|
3254
|
+
if (sinptr->sin_port == 0)
|
3255
|
+
sinptr->sin_port = port;
|
3256
|
+
break;
|
3257
|
+
}
|
3258
|
+
case BOOST_ASIO_OS_DEF(AF_INET6):
|
3259
|
+
{
|
3260
|
+
sockaddr_in6_type* sin6ptr =
|
3261
|
+
reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr);
|
3262
|
+
if (sin6ptr->sin6_port == 0)
|
3263
|
+
sin6ptr->sin6_port = port;
|
3264
|
+
break;
|
3265
|
+
}
|
3266
|
+
default:
|
3267
|
+
break;
|
3268
|
+
}
|
3269
|
+
}
|
3270
|
+
}
|
3271
|
+
#endif
|
3272
|
+
return ec = translate_addrinfo_error(error);
|
3273
|
+
#endif
|
3274
|
+
}
|
3275
|
+
|
3276
|
+
boost::system::error_code background_getaddrinfo(
|
3277
|
+
const weak_cancel_token_type& cancel_token, const char* host,
|
3278
|
+
const char* service, const addrinfo_type& hints,
|
3279
|
+
addrinfo_type** result, boost::system::error_code& ec)
|
3280
|
+
{
|
3281
|
+
if (cancel_token.expired())
|
3282
|
+
ec = boost::asio::error::operation_aborted;
|
3283
|
+
else
|
3284
|
+
socket_ops::getaddrinfo(host, service, hints, result, ec);
|
3285
|
+
return ec;
|
3286
|
+
}
|
3287
|
+
|
3288
|
+
void freeaddrinfo(addrinfo_type* ai)
|
3289
|
+
{
|
3290
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
3291
|
+
# if defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3292
|
+
// Building for Windows XP, Windows Server 2003, or later.
|
3293
|
+
::freeaddrinfo(ai);
|
3294
|
+
# else
|
3295
|
+
// Building for Windows 2000 or earlier.
|
3296
|
+
typedef int (WSAAPI *fai_t)(addrinfo_type*);
|
3297
|
+
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
3298
|
+
{
|
3299
|
+
if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo"))
|
3300
|
+
{
|
3301
|
+
fai(ai);
|
3302
|
+
return;
|
3303
|
+
}
|
3304
|
+
}
|
3305
|
+
freeaddrinfo_emulation(ai);
|
3306
|
+
# endif
|
3307
|
+
#elif !defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3308
|
+
freeaddrinfo_emulation(ai);
|
3309
|
+
#else
|
3310
|
+
::freeaddrinfo(ai);
|
3311
|
+
#endif
|
3312
|
+
}
|
3313
|
+
|
3314
|
+
boost::system::error_code getnameinfo(const socket_addr_type* addr,
|
3315
|
+
std::size_t addrlen, char* host, std::size_t hostlen,
|
3316
|
+
char* serv, std::size_t servlen, int flags, boost::system::error_code& ec)
|
3317
|
+
{
|
3318
|
+
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
|
3319
|
+
# if defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3320
|
+
// Building for Windows XP, Windows Server 2003, or later.
|
3321
|
+
clear_last_error();
|
3322
|
+
int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen),
|
3323
|
+
host, static_cast<DWORD>(hostlen),
|
3324
|
+
serv, static_cast<DWORD>(servlen), flags);
|
3325
|
+
return ec = translate_addrinfo_error(error);
|
3326
|
+
# else
|
3327
|
+
// Building for Windows 2000 or earlier.
|
3328
|
+
typedef int (WSAAPI *gni_t)(const socket_addr_type*,
|
3329
|
+
int, char*, DWORD, char*, DWORD, int);
|
3330
|
+
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
3331
|
+
{
|
3332
|
+
if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
|
3333
|
+
{
|
3334
|
+
clear_last_error();
|
3335
|
+
int error = gni(addr, static_cast<int>(addrlen),
|
3336
|
+
host, static_cast<DWORD>(hostlen),
|
3337
|
+
serv, static_cast<DWORD>(servlen), flags);
|
3338
|
+
return ec = translate_addrinfo_error(error);
|
3339
|
+
}
|
3340
|
+
}
|
3341
|
+
clear_last_error();
|
3342
|
+
return getnameinfo_emulation(addr, addrlen,
|
3343
|
+
host, hostlen, serv, servlen, flags, ec);
|
3344
|
+
# endif
|
3345
|
+
#elif !defined(BOOST_ASIO_HAS_GETADDRINFO)
|
3346
|
+
using namespace std; // For memcpy.
|
3347
|
+
sockaddr_storage_type tmp_addr;
|
3348
|
+
memcpy(&tmp_addr, addr, addrlen);
|
3349
|
+
tmp_addr.ss_len = addrlen;
|
3350
|
+
addr = reinterpret_cast<socket_addr_type*>(&tmp_addr);
|
3351
|
+
clear_last_error();
|
3352
|
+
return getnameinfo_emulation(addr, addrlen,
|
3353
|
+
host, hostlen, serv, servlen, flags, ec);
|
3354
|
+
#else
|
3355
|
+
clear_last_error();
|
3356
|
+
int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
|
3357
|
+
return ec = translate_addrinfo_error(error);
|
3358
|
+
#endif
|
3359
|
+
}
|
3360
|
+
|
3361
|
+
boost::system::error_code sync_getnameinfo(
|
3362
|
+
const socket_addr_type* addr, std::size_t addrlen,
|
3363
|
+
char* host, std::size_t hostlen, char* serv,
|
3364
|
+
std::size_t servlen, int sock_type, boost::system::error_code& ec)
|
3365
|
+
{
|
3366
|
+
// First try resolving with the service name. If that fails try resolving
|
3367
|
+
// but allow the service to be returned as a number.
|
3368
|
+
int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
|
3369
|
+
socket_ops::getnameinfo(addr, addrlen, host,
|
3370
|
+
hostlen, serv, servlen, flags, ec);
|
3371
|
+
if (ec)
|
3372
|
+
{
|
3373
|
+
socket_ops::getnameinfo(addr, addrlen, host, hostlen,
|
3374
|
+
serv, servlen, flags | NI_NUMERICSERV, ec);
|
3375
|
+
}
|
3376
|
+
|
3377
|
+
return ec;
|
3378
|
+
}
|
3379
|
+
|
3380
|
+
boost::system::error_code background_getnameinfo(
|
3381
|
+
const weak_cancel_token_type& cancel_token,
|
3382
|
+
const socket_addr_type* addr, std::size_t addrlen,
|
3383
|
+
char* host, std::size_t hostlen, char* serv,
|
3384
|
+
std::size_t servlen, int sock_type, boost::system::error_code& ec)
|
3385
|
+
{
|
3386
|
+
if (cancel_token.expired())
|
3387
|
+
{
|
3388
|
+
ec = boost::asio::error::operation_aborted;
|
3389
|
+
}
|
3390
|
+
else
|
3391
|
+
{
|
3392
|
+
// First try resolving with the service name. If that fails try resolving
|
3393
|
+
// but allow the service to be returned as a number.
|
3394
|
+
int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
|
3395
|
+
socket_ops::getnameinfo(addr, addrlen, host,
|
3396
|
+
hostlen, serv, servlen, flags, ec);
|
3397
|
+
if (ec)
|
3398
|
+
{
|
3399
|
+
socket_ops::getnameinfo(addr, addrlen, host, hostlen,
|
3400
|
+
serv, servlen, flags | NI_NUMERICSERV, ec);
|
3401
|
+
}
|
3402
|
+
}
|
3403
|
+
|
3404
|
+
return ec;
|
3405
|
+
}
|
3406
|
+
|
3407
|
+
#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3408
|
+
|
3409
|
+
u_long_type network_to_host_long(u_long_type value)
|
3410
|
+
{
|
3411
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3412
|
+
unsigned char* value_p = reinterpret_cast<unsigned char*>(&value);
|
3413
|
+
u_long_type result = (static_cast<u_long_type>(value_p[0]) << 24)
|
3414
|
+
| (static_cast<u_long_type>(value_p[1]) << 16)
|
3415
|
+
| (static_cast<u_long_type>(value_p[2]) << 8)
|
3416
|
+
| static_cast<u_long_type>(value_p[3]);
|
3417
|
+
return result;
|
3418
|
+
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3419
|
+
return ntohl(value);
|
3420
|
+
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3421
|
+
}
|
3422
|
+
|
3423
|
+
u_long_type host_to_network_long(u_long_type value)
|
3424
|
+
{
|
3425
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3426
|
+
u_long_type result;
|
3427
|
+
unsigned char* result_p = reinterpret_cast<unsigned char*>(&result);
|
3428
|
+
result_p[0] = static_cast<unsigned char>((value >> 24) & 0xFF);
|
3429
|
+
result_p[1] = static_cast<unsigned char>((value >> 16) & 0xFF);
|
3430
|
+
result_p[2] = static_cast<unsigned char>((value >> 8) & 0xFF);
|
3431
|
+
result_p[3] = static_cast<unsigned char>(value & 0xFF);
|
3432
|
+
return result;
|
3433
|
+
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3434
|
+
return htonl(value);
|
3435
|
+
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3436
|
+
}
|
3437
|
+
|
3438
|
+
u_short_type network_to_host_short(u_short_type value)
|
3439
|
+
{
|
3440
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3441
|
+
unsigned char* value_p = reinterpret_cast<unsigned char*>(&value);
|
3442
|
+
u_short_type result = (static_cast<u_short_type>(value_p[0]) << 8)
|
3443
|
+
| static_cast<u_short_type>(value_p[1]);
|
3444
|
+
return result;
|
3445
|
+
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3446
|
+
return ntohs(value);
|
3447
|
+
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3448
|
+
}
|
3449
|
+
|
3450
|
+
u_short_type host_to_network_short(u_short_type value)
|
3451
|
+
{
|
3452
|
+
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3453
|
+
u_short_type result;
|
3454
|
+
unsigned char* result_p = reinterpret_cast<unsigned char*>(&result);
|
3455
|
+
result_p[0] = static_cast<unsigned char>((value >> 8) & 0xFF);
|
3456
|
+
result_p[1] = static_cast<unsigned char>(value & 0xFF);
|
3457
|
+
return result;
|
3458
|
+
#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3459
|
+
return htons(value);
|
3460
|
+
#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
|
3461
|
+
}
|
3462
|
+
|
3463
|
+
} // namespace socket_ops
|
3464
|
+
} // namespace detail
|
3465
|
+
} // namespace asio
|
3466
|
+
} // namespace boost
|
3467
|
+
|
3468
|
+
#include <boost/asio/detail/pop_options.hpp>
|
3469
|
+
|
3470
|
+
#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
|