diff --git a/NativeLibs/yasio/yasio/config.hpp b/NativeLibs/yasio/yasio/config.hpp index 4f4e5cf..c3e7264 100644 --- a/NativeLibs/yasio/yasio/config.hpp +++ b/NativeLibs/yasio/yasio/config.hpp @@ -205,7 +205,7 @@ SOFTWARE. /* ** The yasio version macros */ -#define YASIO_VERSION_NUM 0x050000 +#define YASIO_VERSION_NUM 0x040201 /* ** The macros used by io_service. diff --git a/NativeLibs/yasio/yasio/fsutils.hpp b/NativeLibs/yasio/yasio/fsutils.hpp new file mode 100644 index 0000000..46d20ab --- /dev/null +++ b/NativeLibs/yasio/yasio/fsutils.hpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2024 HALX99 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include "yasio/string.hpp" +#include "yasio/string_view.hpp" +#include + +namespace yasio +{ +inline yasio::string read_text_file(cxx17::string_view file_path) +{ + std::ifstream fin(file_path.data(), std::ios_base::binary); + if (fin.is_open()) + { + fin.seekg(std::ios_base::end); + auto n = static_cast(fin.tellg()); + if (n > 0) + { + yasio::string ret; + ret.resize_and_overwrite(n, [&fin](char* out, size_t outlen) { + fin.seekg(std::ios_base::beg); + fin.read(out, outlen); + return outlen; + }); + return ret; + } + } + return yasio::string{}; +} +} // namespace yasio diff --git a/NativeLibs/yasio/yasio/impl/mbedtls.hpp b/NativeLibs/yasio/yasio/impl/mbedtls.hpp index 6a02ab4..618986d 100644 --- a/NativeLibs/yasio/yasio/impl/mbedtls.hpp +++ b/NativeLibs/yasio/yasio/impl/mbedtls.hpp @@ -31,6 +31,8 @@ SOFTWARE. #if YASIO_SSL_BACKEND == 2 +# include "yasio/split.hpp" + YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) { auto ctx = new yssl_ctx_st(); @@ -63,17 +65,16 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) if (yasio__valid_str(opts.crtfile_)) // the cafile_ must be full path { 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); - } + yasio::split( + opts.crtfile_, ',', [&](char* first, char* last) { + yasio::split_term null_term(last); - return !!ret; - }); + 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); + } + }); if (!fail_count) authmode = MBEDTLS_SSL_VERIFY_REQUIRED; } diff --git a/NativeLibs/yasio/yasio/impl/openssl.hpp b/NativeLibs/yasio/yasio/impl/openssl.hpp index 5bacfd6..4c94430 100644 --- a/NativeLibs/yasio/yasio/impl/openssl.hpp +++ b/NativeLibs/yasio/yasio/impl/openssl.hpp @@ -31,6 +31,8 @@ SOFTWARE. #if YASIO_SSL_BACKEND == 1 // OpenSSL +# include "yasio/split.hpp" + // The ssl error mask (1 << 31), a little hack, but works # define YSSL_ERR_MASK 0x80000000 @@ -51,8 +53,8 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) if (yasio__valid_str(opts.crtfile_)) { // CAfile for verify fail_count = 0; - yssl_splitpath(opts.crtfile_, [&](char* first, char* last) { - yssl_split_term null_term(last); + yasio::split(opts.crtfile_, ',', [&](char* first, char* last) { + yasio::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 */ @@ -65,15 +67,13 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) ++fail_count; YASIO_LOG("[global] load ca certifaction file failed!"); } - - return !ok; }); } /* - * client cert & key not implement yet, since it not common usecase - * SSL_CTX_use_certificate_chain_file - * SSL_CTX_use_PrivateKey_file - */ + * client cert & key not implement yet, since it not common usecase + * SSL_CTX_use_certificate_chain_file + * SSL_CTX_use_PrivateKey_file + */ if (!fail_count) { ::SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ::SSL_CTX_get_verify_callback(ctx)); @@ -99,12 +99,12 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) if (yasio__valid_str(opts.keyfile_) && ::SSL_CTX_use_PrivateKey_file(ctx, opts.keyfile_, SSL_FILETYPE_PEM) <= 0) YASIO_LOG("[gobal] load server private key file failed!"); - /* - * If client provide cert, then verify, otherwise skip verify - * Note: if SSL_VERIFY_FAIL_IF_NO_PEER_CERT specified, client must provide - * cert & key which is not common use, means 100% online servers doesn't require - * client to provide cert - */ + /* + * If client provide cert, then verify, otherwise skip verify + * Note: if SSL_VERIFY_FAIL_IF_NO_PEER_CERT specified, client must provide + * cert & key which is not common use, means 100% online servers doesn't require + * client to provide cert + */ ::SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ::SSL_CTX_get_verify_callback(ctx)); } diff --git a/NativeLibs/yasio/yasio/io_service.cpp b/NativeLibs/yasio/yasio/io_service.cpp index 614b8e3..6611c68 100644 --- a/NativeLibs/yasio/yasio/io_service.cpp +++ b/NativeLibs/yasio/yasio/io_service.cpp @@ -695,15 +695,15 @@ void io_transport_kcp::set_primitives() io_transport_udp::set_primitives(); underlaying_write_cb_ = write_cb_; write_cb_ = [this](const void* data, int len, const ip::endpoint*, int& error) { - int nsent = ::ikcp_send(kcp_, static_cast(data), len /*(std::min)(static_cast(kcp_->mss), len)*/); - if (nsent > 0) - { - ::ikcp_flush(kcp_); - expire_time_ = 0; - } - else - error = EMSGSIZE; // emit message too long - return nsent; + int nsent = ::ikcp_send(kcp_, static_cast(data), len /*(std::min)(static_cast(kcp_->mss), len)*/); + if (nsent > 0) + { + ::ikcp_flush(kcp_); + expire_time_ = 0; + } + else + error = EMSGSIZE; // emit message too long + return nsent; }; } bool io_transport_kcp::do_write(highp_time_t& wait_duration) @@ -1225,10 +1225,21 @@ void io_service::do_connect(io_channel* ctx) if (yasio__testbits(ctx->properties_, YCF_EXCLUSIVEADDRUSE)) ctx->socket_->exclusive_address(true); - if (!yasio__testbits(ctx->properties_, YCM_UDS)) - { + if (!yasio__testbits(ctx->properties_, YCM_UDS) && (!ctx->local_host_.empty() || ctx->local_port_ != 0 || yasio__testbits(ctx->properties_, YCM_UDP))) + { // Don't invoke socket.bind for tcp when not require bind network inteface or port explicitly auto ifaddr = ctx->local_host_.empty() ? YASIO_ADDR_ANY(ep.af()) : ctx->local_host_.c_str(); ret = ctx->socket_->bind(ifaddr, ctx->local_port_); + if (ret < 0 && xxsocket::get_last_errno() == EPERM) + { + /* + Supress EPERM: on macos the bind will always fail with EPERM when runs in code signing sandbox mode + even through provide ADDR_ANY and port=0 to require bind a random local endpoint, but on other systems, + require call bind before connect for UDP sockets. + refer issue: https://github.com/yasio/yasio/issues/441 + */ + YASIO_KLOGW("[warning] bind %s:%u fail", ifaddr, ctx->local_port_); + ret = 0; + } } if (ret == 0) diff --git a/NativeLibs/yasio/yasio/singleton.hpp b/NativeLibs/yasio/yasio/singleton.hpp index 70b69ab..09afbf4 100644 --- a/NativeLibs/yasio/yasio/singleton.hpp +++ b/NativeLibs/yasio/yasio/singleton.hpp @@ -92,7 +92,7 @@ class singleton_constructor<_Ty, true> { std::mem_fn(memf)(inst); } - static void delay_init(_Ty* inst) + static void delay_init(_Ty* /*inst*/) { // dummy init without delay init member func, same as no delay constructor } }; diff --git a/NativeLibs/yasio/yasio/split.hpp b/NativeLibs/yasio/yasio/split.hpp new file mode 100644 index 0000000..eb821a8 --- /dev/null +++ b/NativeLibs/yasio/yasio/split.hpp @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2024 HALX99 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/* + * The standard split stub of yasio: + * The pred callback prototype: [](CStr first, CStr last) ->bool{ return true; } + * returns: + * true: want continue split + * false: abort split + * + */ + +#pragma once + +#include "yasio/string_view.hpp" +#include + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 4706) +#endif + +namespace yasio +{ +template +inline void split_if(_CStr s, typename std::remove_pointer<_CStr>::type delim, _Pred&& pred) +{ + auto _Start = s; // the start of every string + auto _Ptr = s; // source string iterator + while ((_Ptr = strchr(_Ptr, delim))) + { + if (_Start <= _Ptr && !pred(_Start, _Ptr)) + return; + _Start = _Ptr + 1; + ++_Ptr; + } + pred(_Start, nullptr); // last one, end is nullptr +} + +template +inline void split_if_n(_CStr s, size_t slen, typename std::remove_pointer<_CStr>::type delim, _Pred&& pred) +{ + auto _Start = s; // the start of every string + auto _Ptr = s; // source string iterator + auto _End = s + slen; + while ((_Ptr = strchr(_Ptr, delim))) + { + if (_Ptr >= _End) + break; + + if (_Start <= _Ptr && !pred(_Start, _Ptr)) + return; + _Start = _Ptr + 1; + ++_Ptr; + } + if (_Start <= _End) + pred(_Start, _End); +} + +template +inline void split(_CStr s, typename std::remove_pointer<_CStr>::type delim, _Func&& func) +{ + split_if(s, delim, [func](_CStr first, _CStr last) { + func(first, last); + return true; + }); +} + +template +inline void split_n(_CStr s, size_t slen, typename std::remove_pointer<_CStr>::type delim, _Func&& func) +{ + split_if_n(s, slen, delim, [func](_CStr first, _CStr last) { + func(first, last); + return true; + }); +} + +struct split_term { + split_term(char* end) + { + if (end) + { + this->val_ = *end; + *end = '\0'; + this->end_ = end; + } + } + ~split_term() + { + if (this->end_) + *this->end_ = this->val_; + } + +private: + char* end_ = nullptr; + char val_ = '\0'; +}; +} // namespace yasio + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif diff --git a/NativeLibs/yasio/yasio/ssl.hpp b/NativeLibs/yasio/yasio/ssl.hpp index 4f2d888..3a54b23 100644 --- a/NativeLibs/yasio/yasio/ssl.hpp +++ b/NativeLibs/yasio/yasio/ssl.hpp @@ -98,50 +98,6 @@ YASIO__DECL int yssl_read(yssl_st* ssl, void* data, size_t len, int& err); #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/impl/openssl.hpp" #elif YASIO_SSL_BACKEND == 2 // mbedtls diff --git a/NativeLibs/yasio/yasio/yasio_fwd.hpp b/NativeLibs/yasio/yasio/yasio_fwd.hpp index e709670..9e2aa16 100644 --- a/NativeLibs/yasio/yasio/yasio_fwd.hpp +++ b/NativeLibs/yasio/yasio/yasio_fwd.hpp @@ -40,7 +40,7 @@ class io_event; class io_channel; typedef class io_transport* transport_handle_t; } // namespace inet -#if !YASIO__HAS_NS_INLINE +#if !YASIO__HAS_CXX11 using namespace yasio::inet; #endif } // namespace yasio