From 1464009e638ce1a91c6adb8df01e279aec3401b7 Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 10 Jan 2023 22:19:30 +0800 Subject: [PATCH] Update yasio to latest --- thirdparty/README.md | 2 +- thirdparty/yasio/detail/config.hpp | 6 +++ thirdparty/yasio/detail/mbedtls.inl | 22 ++++++--- thirdparty/yasio/detail/openssl.inl | 43 ++++++++++++----- thirdparty/yasio/detail/select_fd_set.hpp | 3 +- thirdparty/yasio/detail/signal_blocker.hpp | 55 --------------------- thirdparty/yasio/detail/ssl.hpp | 49 +++++++++++++++++-- thirdparty/yasio/detail/utils.hpp | 28 ++++++++--- thirdparty/yasio/xxsocket.cpp | 19 ++++++++ thirdparty/yasio/xxsocket.hpp | 36 +++++++------- thirdparty/yasio/yasio.cpp | 56 ++++++++++++---------- thirdparty/yasio/yasio.hpp | 4 +- 12 files changed, 193 insertions(+), 130 deletions(-) delete mode 100644 thirdparty/yasio/detail/signal_blocker.hpp diff --git a/thirdparty/README.md b/thirdparty/README.md index eea743649c..5f9eb2a8ff 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -238,7 +238,7 @@ ## yasio - [![Upstream](https://img.shields.io/github/v/release/yasio/yasio?label=Upstream)](https://github.com/yasio/yasio) -- Version: 3.39.6 +- Version: git 3.39.7-2e7723f - License: MIT WITH Anti-996 ## zlib diff --git a/thirdparty/yasio/detail/config.hpp b/thirdparty/yasio/detail/config.hpp index a6f12c9b52..b277f698b2 100644 --- a/thirdparty/yasio/detail/config.hpp +++ b/thirdparty/yasio/detail/config.hpp @@ -227,6 +227,12 @@ SOFTWARE. // https://github.com/c-ares/c-ares/pull/148 #define YASIO_FALLBACK_NAME_SERVERS "8.8.8.8,223.5.5.5,114.114.114.114" +// Since ubuntu 16.04, the /etc/resolv.conf control by systemd-resolved service, +// and the preferred non loopback name server was store to /run/systemd/resolve/resolv.conf +// refer to: https://unix.stackexchange.com/questions/612416/why-does-etc-resolv-conf-point-at-127-0-0-53 +#define YASIO_SYSTEMD_RESOLV_PATH "/run/systemd/resolve/resolv.conf" +#define YASIO_SYSTEMD_RESOLV_PATH_LEN (sizeof(YASIO_SYSTEMD_RESOLV_PATH) - 1) + // The yasio ssl client PIN for server to recognize #define YASIO_SSL_PIN "yasio_ssl_client" #define YASIO_SSL_PIN_LEN (sizeof(YASIO_SSL_PIN) - 1) diff --git a/thirdparty/yasio/detail/mbedtls.inl b/thirdparty/yasio/detail/mbedtls.inl index d50a0b248d..7c1966b26e 100644 --- a/thirdparty/yasio/detail/mbedtls.inl +++ b/thirdparty/yasio/detail/mbedtls.inl @@ -62,13 +62,20 @@ YASIO__DECL ssl_ctx_st* yssl_ctx_new(const yssl_options& opts) int authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; if (yasio__valid_str(opts.crtfile_)) // the cafile_ must be full path { - if ((ret = ::mbedtls_x509_crt_parse_file(&ctx->cert, opts.crtfile_)) == 0) + int fail_count = 0; + yssl_splitpath(opts.crtfile_, [&](char* first, char* last) { + yssl_split_term null_term(last); + + if ((ret = ::mbedtls_x509_crt_parse_file(&ctx->cert, first)) != 0) + { + ++fail_count; + YASIO_LOG("mbedtls_x509_crt_parse_file with ret=-0x%x", (unsigned int)-ret); + } + + return !!ret; + }); + if (!fail_count) authmode = MBEDTLS_SSL_VERIFY_REQUIRED; - else - { - YASIO_LOG("mbedtls_x509_crt_parse_file with ret=-0x%x", (unsigned int)-ret); - break; - } } if (opts.client) @@ -127,7 +134,8 @@ YASIO__DECL ssl_st* yssl_new(ssl_ctx_st* ctx, int fd, const char* hostname, bool // ssl_set_fd ssl->bio.fd = fd; ::mbedtls_ssl_set_bio(ssl, &ssl->bio, ::mbedtls_net_send, ::mbedtls_net_recv, nullptr /* rev_timeout() */); - ::mbedtls_ssl_set_hostname(ssl, hostname); + if (client) + ::mbedtls_ssl_set_hostname(ssl, hostname); return ssl; } YASIO__DECL void yssl_shutdown(ssl_st*& ssl) diff --git a/thirdparty/yasio/detail/openssl.inl b/thirdparty/yasio/detail/openssl.inl index 89a04f1da1..5c3eae0d6b 100644 --- a/thirdparty/yasio/detail/openssl.inl +++ b/thirdparty/yasio/detail/openssl.inl @@ -47,27 +47,44 @@ YASIO__DECL ssl_ctx_st* yssl_ctx_new(const yssl_options& opts) if (opts.client) { + int fail_count = -1; if (yasio__valid_str(opts.crtfile_)) { - if (::SSL_CTX_load_verify_locations(ctx, opts.crtfile_, nullptr) == 1) - { - ::SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ::SSL_CTX_get_verify_callback(ctx)); + fail_count = 0; + yssl_splitpath(opts.crtfile_, [&](char* first, char* last) { + yssl_split_term null_term(last); + +# if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) + /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ + bool ok = ::SSL_CTX_load_verify_file(ctx, first) == 1; +# else + bool ok = ::SSL_CTX_load_verify_locations(ctx, first, nullptr) == 1; +# endif + if (!ok) + { + ++fail_count; + YASIO_LOG("[global] load ca certifaction file failed!"); + } + + return !ok; + }); + } + if (!fail_count) + { + ::SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ::SSL_CTX_get_verify_callback(ctx)); # if OPENSSL_VERSION_NUMBER >= 0x10101000L - ::SSL_CTX_set_post_handshake_auth(ctx, 1); + ::SSL_CTX_set_post_handshake_auth(ctx, 1); # endif # if defined(X509_V_FLAG_PARTIAL_CHAIN) - /* Have intermediate certificates in the trust store be treated as - trust-anchors, in the same way as self-signed root CA certificates - are. This allows users to verify servers using the intermediate cert - only, instead of needing the whole chain. */ - X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), X509_V_FLAG_PARTIAL_CHAIN); + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. */ + ::X509_STORE_set_flags(::SSL_CTX_get_cert_store(ctx), X509_V_FLAG_PARTIAL_CHAIN); # endif - } - else - YASIO_LOG("[global] load ca certifaction file failed!"); } else - SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); + ::SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); } else { diff --git a/thirdparty/yasio/detail/select_fd_set.hpp b/thirdparty/yasio/detail/select_fd_set.hpp index 8cd5aa5fa3..9822c0f6a1 100644 --- a/thirdparty/yasio/detail/select_fd_set.hpp +++ b/thirdparty/yasio/detail/select_fd_set.hpp @@ -10,6 +10,7 @@ #pragma once #include +#include #include "yasio/detail/socket.hpp" namespace yasio @@ -38,7 +39,7 @@ public: int poll_io(int waitd_ms) { - timeval waitd_tv = {(decltype(timeval::tv_sec))(waitd_ms / 1000), (decltype(timeval::tv_usec))(waitd_ms % 1000)}; + timeval waitd_tv = {(decltype(timeval::tv_sec))(waitd_ms / std::milli::den), (decltype(timeval::tv_usec))(waitd_ms % std::milli::den)}; return ::select(this->max_descriptor_, &(fd_set_[read_op]), &(fd_set_[write_op]), nullptr, &waitd_tv); } diff --git a/thirdparty/yasio/detail/signal_blocker.hpp b/thirdparty/yasio/detail/signal_blocker.hpp deleted file mode 100644 index d563787122..0000000000 --- a/thirdparty/yasio/detail/signal_blocker.hpp +++ /dev/null @@ -1,55 +0,0 @@ - -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -// -// detail/signal_blocker.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2012-2023 HALX99 (halx99 at live dot com) - -#pragma once - -#include "yasio/compiler/feature_test.hpp" - -#if !defined(_WIN32) -#include -#include -#endif - -namespace yasio -{ -YASIO__NS_INLINE -namespace inet -{ -#if defined(_WIN32) -class signal_blocker {}; -#else -class signal_blocker { -public: - // Constructor blocks all signals for the calling thread. - signal_blocker() : blocked_(false) - { - sigset_t new_mask; - sigfillset(&new_mask); - blocked_ = (pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_) == 0); - } - - // Destructor restores the previous signal mask. - ~signal_blocker() - { - if (blocked_) - pthread_sigmask(SIG_SETMASK, &old_mask_, 0); - } - -private: - // Have signals been blocked. - bool blocked_; - - // The previous signal mask. - sigset_t old_mask_; -}; -#endif -} // namespace inet -} // namespace yasio diff --git a/thirdparty/yasio/detail/ssl.hpp b/thirdparty/yasio/detail/ssl.hpp index c07413741d..788ab16ab1 100644 --- a/thirdparty/yasio/detail/ssl.hpp +++ b/thirdparty/yasio/detail/ssl.hpp @@ -58,8 +58,8 @@ struct ssl_st : public mbedtls_ssl_context { #if defined(YASIO_SSL_BACKEND) struct yssl_options { - const char* crtfile_; - const char* keyfile_; + char* crtfile_; + char* keyfile_; bool client; }; @@ -87,7 +87,50 @@ YASIO__DECL int yssl_read(ssl_st* ssl, void* data, size_t len, int& err); /////////////////////////////////////////////////////////////////// // --- Implement common yasio ssl api with different ssl backends -#define yasio__valid_str(str) (str && *str) +#define yasio__valid_str(cstr) (cstr && *cstr) +#define yasio__c_str(str) (!str.empty() ? &str.front() : nullptr) + +/* private use for split cert files */ +template +inline bool yssl_splitpath(char* str, _Fty&& func) +{ + auto _Start = str; // the start of every string + auto _Ptr = str; // source string iterator + bool aborted = false; + while ((_Ptr = strchr(_Ptr, ','))) + { + if (_Start <= _Ptr) + { + if ((aborted = func(_Start, _Ptr))) + break; + } + _Start = _Ptr + 1; + ++_Ptr; + } + + if (!aborted) + aborted = func(_Start, nullptr); // last one + return aborted; +} + +struct yssl_split_term { + yssl_split_term(char* end) + { + if (end) { + this->val_ = *end; + *end = '\0'; + this->end_ = end; + } + } + ~yssl_split_term() + { + if (this->end_) + *this->end_ = this->val_; + } +private: + char* end_ = nullptr; + char val_ = '\0'; +}; #if YASIO_SSL_BACKEND == 1 // openssl # include "yasio/detail/openssl.inl" diff --git a/thirdparty/yasio/detail/utils.hpp b/thirdparty/yasio/detail/utils.hpp index 5972f4c6aa..46a79f47d8 100644 --- a/thirdparty/yasio/detail/utils.hpp +++ b/thirdparty/yasio/detail/utils.hpp @@ -1,5 +1,5 @@ ////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any // client application. ////////////////////////////////////////////////////////////////////////////////////////// /* @@ -28,6 +28,7 @@ SOFTWARE. #ifndef YASIO__UTILS_HPP #define YASIO__UTILS_HPP #include +#include #include #include #include "yasio/compiler/feature_test.hpp" @@ -40,18 +41,21 @@ typedef std::chrono::high_resolution_clock steady_clock_t; typedef std::chrono::system_clock system_clock_t; // The high precision nano seconds timestamp since epoch -template inline highp_time_t xhighp_clock() +template +inline highp_time_t xhighp_clock() { auto duration = _Ty::now().time_since_epoch(); return std::chrono::duration_cast(duration).count(); } // The high precision micro seconds timestamp since epoch -template inline highp_time_t highp_clock() +template +inline highp_time_t highp_clock() { return xhighp_clock<_Ty>() / std::milli::den; } // The normal precision milli seconds timestamp since epoch -template inline highp_time_t clock() +template +inline highp_time_t clock() { return xhighp_clock<_Ty>() / std::micro::den; } @@ -63,14 +67,26 @@ inline highp_time_t time_now() { return ::time(nullptr); } #if YASIO__HAS_CXX17 using std::clamp; #else -template const _Ty& clamp(const _Ty& v, const _Ty& lo, const _Ty& hi) +template +const _Ty& clamp(const _Ty& v, const _Ty& lo, const _Ty& hi) { assert(!(hi < lo)); return v < lo ? lo : hi < v ? hi : v; } #endif -template inline void invoke_dtor(_Ty* p) { p->~_Ty(); } +template +inline void invoke_dtor(_Ty* p) +{ + p->~_Ty(); +} + +inline bool is_regular_file(const char* path) +{ + struct stat st; + return (::stat(path, &st) == 0) && (st.st_mode & S_IFREG); +} + } // namespace yasio #endif diff --git a/thirdparty/yasio/xxsocket.cpp b/thirdparty/yasio/xxsocket.cpp index dfbe8ac8d6..1a775d3a23 100644 --- a/thirdparty/yasio/xxsocket.cpp +++ b/thirdparty/yasio/xxsocket.cpp @@ -384,7 +384,26 @@ xxsocket& xxsocket::swap(xxsocket& rhs) bool xxsocket::open(int af, int type, int protocol) { if (invalid_socket == this->fd) + { +# if defined(_WIN32) + this->fd = ::socket(af, type, protocol); + //socket_native_type s = ::WSASocketW(af, type, protocol, 0, 0, WSA_FLAG_OVERLAPPED); + ////get_last_error(ec, s == invalid_socket); + //if (s == invalid_socket) + // return false; + //this->fd = s; + //if (af == ASIO_OS_DEF(AF_INET6)) + //{ + // // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to + // // false. This will only succeed on Windows Vista and later versions of + // // Windows, where a dual-stack IPv4/v6 implementation is available. + // DWORD optval = 0; + // ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast(&optval), sizeof(optval)); + //} +#else this->fd = ::socket(af, type, protocol); +#endif + } return is_open(); } diff --git a/thirdparty/yasio/xxsocket.hpp b/thirdparty/yasio/xxsocket.hpp index c607c8bbca..6e313a1d9d 100644 --- a/thirdparty/yasio/xxsocket.hpp +++ b/thirdparty/yasio/xxsocket.hpp @@ -62,7 +62,7 @@ namespace ip { #pragma pack(push, 1) // ip packet -struct ip_header { +struct ip_hdr_st { // header size; 5+ unsigned char header_length : 4; @@ -106,7 +106,7 @@ struct ip_header { unsigned char protocol; // TCP / UDP / Other // check header of IP-PACKET 's correctness. - unsigned short checksum; + unsigned short sum; typedef union { unsigned int value; @@ -122,7 +122,7 @@ struct ip_header { dotted_decimal_t dst_ip; }; -struct psd_header { +struct psd_hdr_st { unsigned long src_addr; unsigned long dst_addr; char mbz; @@ -130,7 +130,7 @@ struct psd_header { unsigned short tcp_length; }; -struct tcp_header { +struct tcp_hdr_st { unsigned short src_port; // lgtm [cpp/class-many-fields] unsigned short dst_port; unsigned int seqno; @@ -139,32 +139,32 @@ struct tcp_header { unsigned char reserved : 4; unsigned char flg_fin : 1, flg_syn : 1, flg_rst : 1, flg_psh : 1, flg_ack : 1, flg_urg : 1, flg_reserved : 2; unsigned short win_length; - unsigned short checksum; + unsigned short sum; unsigned short urp; }; -struct udp_header { +struct udp_hdr_st { unsigned short src_port; unsigned short dst_port; unsigned short length; - unsigned short checksum; + unsigned short sum; }; -struct icmp_header { - unsigned char type; // 8bit type - unsigned char code; // 8bit code - unsigned short checksum; // 16bit check sum - unsigned short id; // identifier: usually use process id - unsigned short seqno; // message sequence NO. +struct icmp_hdr_st { + unsigned char type; // 8bit type + unsigned char code; // 8bit code + unsigned short sum; // 16bit check sum + unsigned short id; // identifier: usually use process id + unsigned short seqno; // message sequence NO. }; -struct eth_header { +struct eth_hdr_st { unsigned dst_eth[6]; unsigned src_eth[6]; unsigned eth_type; }; -struct arp_header { +struct arp_hdr_st { unsigned short arp_hw; // format of hardware address unsigned short arp_pro; // format of protocol address unsigned char arp_hlen; // length of hardware address @@ -176,9 +176,9 @@ struct arp_header { unsigned long arp_tpa; // target protocol address; }; -struct arp_packet { - eth_header ethhdr; - arp_header arphdr; +struct arp_packet_st { + eth_hdr_st ethhdr; + arp_hdr_st arphdr; }; #pragma pack(pop) diff --git a/thirdparty/yasio/yasio.cpp b/thirdparty/yasio/yasio.cpp index 501bb57399..e9a8e1d19a 100644 --- a/thirdparty/yasio/yasio.cpp +++ b/thirdparty/yasio/yasio.cpp @@ -39,7 +39,6 @@ SOFTWARE. #include #include #include "yasio/detail/thread_name.hpp" -#include "yasio/detail/signal_blocker.hpp" #if defined(YASIO_SSL_BACKEND) # include "yasio/detail/ssl.hpp" @@ -207,7 +206,7 @@ io_channel::io_channel(io_service& service, int index) : io_base(), service_(ser socket_ = std::make_shared(); state_ = io_base::state::CLOSED; index_ = index; - decode_len_ = [=](void* ptr, int len) { return this->__builtin_decode_len(ptr, len); }; + decode_len_ = [this](void* ptr, int len) { return this->__builtin_decode_len(ptr, len); }; } #if defined(YASIO_SSL_BACKEND) SSL_CTX* io_channel::get_ssl_context(bool client) const @@ -443,13 +442,13 @@ void io_transport::complete_op(io_send_op* op, int error) } void io_transport::set_primitives() { - this->write_cb_ = [=](const void* data, int len, const ip::endpoint*, int& error) { + this->write_cb_ = [this](const void* data, int len, const ip::endpoint*, int& error) { int n = socket_->send(data, len); if (n < 0) error = xxsocket::get_last_errno(); return n; }; - this->read_cb_ = [=](void* data, int len, int revent, int& error) { + this->read_cb_ = [this](void* data, int len, int revent, int& error) { if (revent) { int n = socket_->recv(data, len); @@ -478,13 +477,13 @@ int io_transport_ssl::do_ssl_handshake(int& error) if (ret == 0) // handshake succeed { // because we invoke handshake in call_read, so we emit EWOULDBLOCK to mark ssl transport status `ok` this->state_ = io_base::state::OPENED; - this->read_cb_ = [=](void* data, int len, int revent, int& error) { + this->read_cb_ = [this](void* data, int len, int revent, int& error) { if (revent) return yssl_read(ssl_, data, len, error); error = EWOULDBLOCK; return -1; }; - this->write_cb_ = [=](const void* data, int len, const ip::endpoint*, int& error) { return yssl_write(ssl_, data, len, error); }; + this->write_cb_ = [this](const void* data, int len, const ip::endpoint*, int& error) { return yssl_write(ssl_, data, len, error); }; YASIO_KLOGD("[index: %d] the connection #%u <%s> --> <%s> is established.", ctx_->index_, this->id_, this->local_endpoint().to_string().c_str(), this->remote_endpoint().to_string().c_str()); @@ -517,7 +516,7 @@ void io_transport_ssl::do_ssl_shutdown() } void io_transport_ssl::set_primitives() { - this->read_cb_ = [=](void* /*data*/, int /*len*/, int /*revent*/, int& error) { return do_ssl_handshake(error); }; + this->read_cb_ = [this](void* /*data*/, int /*len*/, int /*revent*/, int& error) { return do_ssl_handshake(error); }; } #endif // ----------------------- io_transport_udp ---------------- @@ -589,7 +588,7 @@ void io_transport_udp::set_primitives() io_transport::set_primitives(); else { - this->write_cb_ = [=](const void* data, int len, const ip::endpoint* destination, int& error) { + this->write_cb_ = [this](const void* data, int len, const ip::endpoint* destination, int& error) { assert(destination); int n = socket_->sendto(data, len, *destination); if (n < 0) @@ -600,7 +599,7 @@ void io_transport_udp::set_primitives() } return n; }; - this->read_cb_ = [=](void* data, int len, int revent, int& error) { + this->read_cb_ = [this](void* data, int len, int revent, int& error) { if (revent) { ip::endpoint peer; @@ -735,8 +734,6 @@ void io_service::start(event_cb_t cb) this->state_ = io_service::state::RUNNING; if (!options_.no_new_thread_) { - signal_blocker sb; - (void)sb; this->worker_ = std::thread(&io_service::run, this); this->worker_id_ = worker_.get_id(); } @@ -805,7 +802,7 @@ void io_service::initialize(const io_hostent* channel_eps, int channel_count) if (channel_count < 1) channel_count = 1; - options_.resolv_ = [=](std::vector& eps, const char* host, unsigned short port) { return this->resolve(eps, host, port); }; + options_.resolv_ = [this](std::vector& eps, const char* host, unsigned short port) { return this->resolve(eps, host, port); }; register_descriptor(interrupter_.read_descriptor(), socket_event::read); // create channels @@ -894,11 +891,9 @@ void io_service::run() do { - auto wait_duration = get_timeout(this->wait_duration_); // Gets current wait duration - this->wait_duration_ = yasio__max_wait_usec; // Reset next wait duration + fd_set = this->fd_set_; - fd_set = this->fd_set_; - timeval waitd_tv = {(decltype(timeval::tv_sec))(wait_duration / 1000000), (decltype(timeval::tv_usec))(wait_duration % 1000000)}; + const auto waitd_usec = get_timeout(this->wait_duration_); // Gets current wait duration #if defined(YASIO_HAVE_CARES) /** * retrieves the set of file descriptors which the calling application should poll io, @@ -907,10 +902,13 @@ void io_service::run() * https://c-ares.org/ares_timeout.html * https://c-ares.org/ares_process_fd.html */ - auto ares_nfds = do_ares_fds(ares_socks, fd_set, waitd_tv); + timeval waitd_tv = {(decltype(timeval::tv_sec))(waitd_usec / std::micro::den), (decltype(timeval::tv_usec))(waitd_usec % std::micro::den)}; + auto ares_nfds = do_ares_fds(ares_socks, fd_set, waitd_tv); + const auto waitd_ms = static_cast(waitd_tv.tv_sec * std::milli::den + waitd_tv.tv_usec / std::milli::den); +#else + const auto waitd_ms = static_cast(waitd_usec / std::milli::den); #endif - const int waitd_ms = static_cast(waitd_tv.tv_sec * 1000 + waitd_tv.tv_usec / 1000); if (waitd_ms > 0) { YASIO_KLOGV("[core] poll_io max_nfds=%d, waiting... %ld milliseconds", fd_set.max_descriptor(), waitd_ms); @@ -1219,8 +1217,8 @@ void io_service::do_connect_completion(io_channel* ctx, fd_set_adapter& fd_set) #if defined(YASIO_SSL_BACKEND) SSL_CTX* io_service::init_ssl_context(ssl_role role) { - auto ctx = role == YSSL_CLIENT ? yssl_ctx_new(yssl_options{options_.cafile_.c_str(), nullptr, true}) - : yssl_ctx_new(yssl_options{options_.crtfile_.c_str(), options_.keyfile_.c_str(), false}); + auto ctx = role == YSSL_CLIENT ? yssl_ctx_new(yssl_options{yasio__c_str(options_.cafile_), nullptr, true}) + : yssl_ctx_new(yssl_options{yasio__c_str(options_.crtfile_), yasio__c_str(options_.keyfile_), false}); ssl_roles_[role] = ctx; return ctx; } @@ -1309,10 +1307,18 @@ void io_service::recreate_ares_channel() if (ares_) destroy_ares_channel(); + int optmask = ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES /* | ARES_OPT_LOOKUPS*/; ares_options options = {}; options.timeout = static_cast(this->options_.dns_queries_timeout_ / std::milli::den); options.tries = this->options_.dns_queries_tries_; - int status = ::ares_init_options(&ares_, &options, ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES /* | ARES_OPT_LOOKUPS*/); +# if defined(__linux__) && !defined(__ANDROID__) + if (yasio::is_regular_file(YASIO_SYSTEMD_RESOLV_PATH)) + { + options.resolvconf_path = strndup(YASIO_SYSTEMD_RESOLV_PATH, YASIO_SYSTEMD_RESOLV_PATH_LEN); + optmask |= ARES_OPT_RESOLVCONF; + } +# endif + int status = ::ares_init_options(&ares_, &options, optmask); if (status == ARES_SUCCESS) { YASIO_KLOGD("[c-ares] create channel succeed"); @@ -1806,6 +1812,8 @@ void io_service::process_timers() } highp_time_t io_service::get_timeout(highp_time_t usec) { + this->wait_duration_ = yasio__max_wait_usec; // Reset next wait duration per frame + if (this->timer_queue_.empty()) return usec; @@ -1905,11 +1913,11 @@ void io_service::start_query(io_channel* ctx) #endif #if !defined(YASIO_HAVE_CARES) // init async name query thread state - std::string resolving_host = ctx->remote_host_; - u_short resolving_port = ctx->remote_port_; + auto resolving_host = ctx->remote_host_; + auto resolving_port = ctx->remote_port_; std::weak_ptr weak_mutex = life_mutex_; std::weak_ptr life_token = life_token_; - std::thread async_resolv_thread([=] { + std::thread async_resolv_thread([this, life_token, weak_mutex, resolving_host, resolving_port, ctx] { // check life token if (life_token.use_count() < 1) return; diff --git a/thirdparty/yasio/yasio.hpp b/thirdparty/yasio/yasio.hpp index 2adbbc52db..bea78703a1 100644 --- a/thirdparty/yasio/yasio.hpp +++ b/thirdparty/yasio/yasio.hpp @@ -1048,6 +1048,8 @@ public: // Gets channel by index YASIO__DECL io_channel* channel_at(size_t index) const; + YASIO__DECL static const char* strerror(int error); + private: YASIO__DECL void do_stop(uint8_t flags); YASIO__DECL void schedule_timer(highp_timer*, timer_cb_t&&); @@ -1151,8 +1153,6 @@ private: YASIO__DECL void do_accept(io_channel*); YASIO__DECL void do_accept_completion(io_channel*, fd_set_adapter& fd_set); - YASIO__DECL static const char* strerror(int error); - /* ** summary: For udp-server only, make dgram handle to communicate with client */