Update yasio to v3.37.6

This commit is contained in:
halx99 2021-10-23 21:51:50 +08:00
parent 8d9266d2bb
commit 5270e1afd6
9 changed files with 168 additions and 89 deletions

View File

@ -223,7 +223,7 @@
## yasio ## yasio
- Upstream: https://github.com/yasio/yasio - Upstream: https://github.com/yasio/yasio
- Version: git 3.37.5-4e8b63a(2641) - Version: 3.37.6
- License: MIT WITH Anti-996 - License: MIT WITH Anti-996
## zlib ## zlib

View File

@ -35,92 +35,126 @@ SOFTWARE.
# include <shared_mutex> # include <shared_mutex>
#else #else
# include <system_error> # include <system_error>
# if defined(_WIN32)
# if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN
# endif
# include <Windows.h>
# define yasio__smtx_t SRWLOCK
# define yasio__smtx_init(rwlock, attr) InitializeSRWLock(rwlock)
# define yasio__smtx_destroy(rwlock)
# define yasio__smtx_lock_shared(rwlock) AcquireSRWLockShared(rwlock)
# define yasio__smtx_trylock_shared(rwlock) !!TryAcquireSRWLockShared(rwlock)
# define yasio__smtx_lock_exclusive(rwlock) AcquireSRWLockExclusive(rwlock)
# define yasio__smtx_trylock_exclusive(rwlock) !!TryAcquireSRWLockExclusive(rwlock)
# define yasio__smtx_unlock_shared(rwlock) ReleaseSRWLockShared(rwlock)
# define yasio__smtx_unlock_exclusive(rwlock) ReleaseSRWLockExclusive(rwlock)
# else
# include <pthread.h>
# define yasio__smtx_t pthread_rwlock_t
# define yasio__smtx_init(rwlock, attr) pthread_rwlock_init(rwlock, attr)
# define yasio__smtx_destroy(rwlock) pthread_rwlock_destroy(rwlock)
# define yasio__smtx_lock_shared(rwlock) pthread_rwlock_rdlock(rwlock)
# define yasio__smtx_trylock_shared(rwlock) pthread_rwlock_tryrdlock(rwlock) != 0
# define yasio__smtx_lock_exclusive(rwlock) pthread_rwlock_wrlock(rwlock)
# define yasio__smtx_trylock_exclusive(rwlock) pthread_rwlock_trywrlock(rwlock) != 0
# define yasio__smtx_unlock_shared(rwlock) pthread_rwlock_unlock(rwlock)
# define yasio__smtx_unlock_exclusive(rwlock) pthread_rwlock_unlock(rwlock)
# endif
# define yaso__throw_error(e) YASIO__THROW0(std::system_error(std::make_error_code(e), ""))
# include <mutex> # include <mutex>
# include <condition_variable>
// CLASS TEMPLATE shared_lock # define yaso__throw_error(e) YASIO__THROW0(std::system_error(std::make_error_code(e), ""))
namespace cxx17 namespace cxx17
{ {
// CLASS TEMPLATE shared_mutex, copy from: https://github.com/boostorg/thread/blob/develop/include/boost/thread/v2/shared_mutex.hpp
class shared_mutex { class shared_mutex {
public: typedef std::mutex mutex_t;
typedef yasio__smtx_t* native_handle_type; typedef std::condition_variable cond_t;
typedef unsigned count_t;
shared_mutex() // strengthened mutex_t mut_;
cond_t gate1_;
// the gate2_ condition variable is only used by functions that
// have taken write_entered_ but are waiting for no_readers()
cond_t gate2_;
count_t state_;
static const count_t write_entered_ = 1U << (sizeof(count_t) * CHAR_BIT - 1);
static const count_t n_readers_ = ~write_entered_;
bool no_writer() const { return (state_ & write_entered_) == 0; }
bool one_writer() const { return (state_ & write_entered_) != 0; }
bool no_writer_no_readers() const
{ {
yasio__smtx_init(&this->_Myhandle, nullptr); // return (state_ & write_entered_) == 0 &&
// (state_ & n_readers_) == 0;
return state_ == 0;
} }
~shared_mutex() { yasio__smtx_destroy(&this->_Myhandle); } bool no_writer_no_max_readers() const { return (state_ & write_entered_) == 0 && (state_ & n_readers_) != n_readers_; }
void lock() /* strengthened */ bool no_readers() const { return (state_ & n_readers_) == 0; }
{ // lock exclusive
yasio__smtx_lock_exclusive(&this->_Myhandle); bool one_or_more_readers() const { return (state_ & n_readers_) > 0; }
shared_mutex(shared_mutex const&) = delete;
shared_mutex& operator=(shared_mutex const&) = delete;
public:
shared_mutex() : state_(0) {}
~shared_mutex() { std::lock_guard<mutex_t> _(mut_); }
// Exclusive ownership
void lock()
{
std::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, std::bind(&shared_mutex::no_writer, std::ref(*this)));
state_ |= write_entered_;
gate2_.wait(lk, std::bind(&shared_mutex::no_readers, std::ref(*this)));
}
bool try_lock()
{
std::unique_lock<mutex_t> lk(mut_);
if (!no_writer_no_readers())
{
return false;
}
state_ = write_entered_;
return true;
}
void unlock()
{
std::lock_guard<mutex_t> _(mut_);
assert(one_writer());
assert(no_readers());
state_ = 0;
// notify all since multiple *lock_shared*() calls may be able
// to proceed in response to this notification
gate1_.notify_all();
} }
bool try_lock() /* strengthened */ // Shared ownership
{ // try to lock exclusive
return yasio__smtx_trylock_exclusive(&this->_Myhandle); void lock_shared()
{
std::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, std::bind(&shared_mutex::no_writer_no_max_readers, std::ref(*this)));
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
} }
bool try_lock_shared()
void unlock() /* strengthened */ {
{ // unlock exclusive std::unique_lock<mutex_t> lk(mut_);
yasio__smtx_unlock_exclusive(&this->_Myhandle); if (!no_writer_no_max_readers())
{
return false;
} }
count_t num_readers = (state_ & n_readers_) + 1;
void lock_shared() /* strengthened */ state_ &= ~n_readers_;
{ // lock non-exclusive state_ |= num_readers;
yasio__smtx_lock_shared(&this->_Myhandle); return true;
} }
void unlock_shared()
bool try_lock_shared() /* strengthened */ {
{ // try to lock non-exclusive std::lock_guard<mutex_t> _(mut_);
return yasio__smtx_trylock_shared(&this->_Myhandle); assert(one_or_more_readers());
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (no_writer())
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
} }
else
void unlock_shared() /* strengthened */ {
{ // unlock non-exclusive if (num_readers == 0)
yasio__smtx_unlock_shared(&this->_Myhandle); gate2_.notify_one();
} }
native_handle_type native_handle() /* strengthened */
{ // get native handle
return &_Myhandle;
} }
shared_mutex(const shared_mutex&) = delete;
shared_mutex& operator=(const shared_mutex&) = delete;
private:
yasio__smtx_t _Myhandle; // the lock object
}; };
// CLASS TEMPLATE shared_lock // CLASS TEMPLATE shared_lock
template <class _Mutex> class shared_lock { // shareable lock template <class _Mutex>
class shared_lock {
public: public:
using mutex_type = _Mutex; using mutex_type = _Mutex;

View File

@ -36,7 +36,7 @@ See: https://github.com/bitwizeshift/string_view-standalone
#include "yasio/compiler/feature_test.hpp" #include "yasio/compiler/feature_test.hpp"
/// wcsncasecmp workaround for android API level < 23, copy from msvc ucrt 10.0.18362.0 'wcsnicmp' /// wcsncasecmp workaround for android API level < 23, copy from msvc ucrt 10.0.18362.0 'wcsnicmp'
#if defined(__ANDROID_API__) && __ANDROID_API__ < 23 #if (defined(__ANDROID_API__) && __ANDROID_API__ < 23) || defined(__MINGW32__)
inline int wcsncasecmp(wchar_t const* const lhs, wchar_t const* const rhs, size_t const count) inline int wcsncasecmp(wchar_t const* const lhs, wchar_t const* const rhs, size_t const count)
{ {
if (count == 0) if (count == 0)

View File

@ -186,7 +186,7 @@ SOFTWARE.
/* /*
** The yasio version macros ** The yasio version macros
*/ */
#define YASIO_VERSION_NUM 0x033705 #define YASIO_VERSION_NUM 0x033706
/* /*
** The macros used by io_service. ** The macros used by io_service.
@ -220,6 +220,6 @@ SOFTWARE.
// https://c-ares.haxx.se/changelog.html // https://c-ares.haxx.se/changelog.html
// https://github.com/c-ares/c-ares/issues/276 // https://github.com/c-ares/c-ares/issues/276
// https://github.com/c-ares/c-ares/pull/148 // https://github.com/c-ares/c-ares/pull/148
#define YASIO_CARES_FALLBACK_DNS "8.8.8.8,223.5.5.5,114.114.114.114" #define YASIO_FALLBACK_NAME_SERVERS "8.8.8.8,223.5.5.5,114.114.114.114"
#endif #endif

View File

@ -29,13 +29,23 @@ SOFTWARE.
#ifndef YASIO__SOCKET_HPP #ifndef YASIO__SOCKET_HPP
#define YASIO__SOCKET_HPP #define YASIO__SOCKET_HPP
#include "yasio/detail/config.hpp"
#ifdef _WIN32 #ifdef _WIN32
# if !defined(WIN32_LEAN_AND_MEAN) # if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
# endif # endif
# include <WinSock2.h> # include <WinSock2.h>
# include <Windows.h> # include <Windows.h>
# if defined(_WIN32) && !defined(_WINSTORE) # if defined(YASIO_INSIDE_UNREAL)
# if !defined(TRUE)
# define TRUE 1
# endif
# if !defined(FALSE)
# define FALSE 0
# endif
# endif
# if !defined(_WINSTORE)
# include <Mswsock.h> # include <Mswsock.h>
# include <Mstcpip.h> # include <Mstcpip.h>
# endif # endif
@ -185,7 +195,17 @@ typedef int socket_native_type;
#define IN_MAX_ADDRSTRLEN INET6_ADDRSTRLEN #define IN_MAX_ADDRSTRLEN INET6_ADDRSTRLEN
#if !defined(_WS2IPDEF_) // Workaround for older MinGW missing AI_XXX macros
#if defined(__MINGW32__)
# if !defined(AI_ALL)
# define AI_ALL 0x00000100
# endif
# if !defined(AI_V4MAPPED)
# define AI_V4MAPPED 0x00000800
# endif
#endif
#if !defined(_WS2IPDEF_) || defined(__MINGW32__)
inline bool IN4_IS_ADDR_LOOPBACK(const in_addr* a) inline bool IN4_IS_ADDR_LOOPBACK(const in_addr* a)
{ {
return ((a->s_addr & 0xff) == 0x7f); // 127/8 return ((a->s_addr & 0xff) == 0x7f); // 127/8

View File

@ -460,8 +460,8 @@ bool xxsocket::open_ex(int af, int type, int protocol)
bool xxsocket::accept_ex(SOCKET sockfd_listened, SOCKET sockfd_prepared, PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength, bool xxsocket::accept_ex(SOCKET sockfd_listened, SOCKET sockfd_prepared, PVOID lpOutputBuffer, DWORD dwReceiveDataLength, DWORD dwLocalAddressLength,
DWORD dwRemoteAddressLength, LPDWORD lpdwBytesReceived, LPOVERLAPPED lpOverlapped) DWORD dwRemoteAddressLength, LPDWORD lpdwBytesReceived, LPOVERLAPPED lpOverlapped)
{ {
return __accept_ex(sockfd_listened, sockfd_prepared, lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, return !!__accept_ex(sockfd_listened, sockfd_prepared, lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived,
lpOverlapped) != FALSE; lpOverlapped);
} }
bool xxsocket::connect_ex(SOCKET s, const struct sockaddr* name, int namelen, PVOID lpSendBuffer, DWORD dwSendDataLength, LPDWORD lpdwBytesSent, bool xxsocket::connect_ex(SOCKET s, const struct sockaddr* name, int namelen, PVOID lpSendBuffer, DWORD dwSendDataLength, LPDWORD lpdwBytesSent,

View File

@ -38,9 +38,8 @@ SOFTWARE.
#include <vector> #include <vector>
#include <chrono> #include <chrono>
#include <functional> #include <functional>
#include "yasio/detail/config.hpp"
#include "yasio/detail/logging.hpp"
#include "yasio/detail/socket.hpp" #include "yasio/detail/socket.hpp"
#include "yasio/detail/logging.hpp"
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)

View File

@ -1334,13 +1334,14 @@ void io_service::init_ssl_context()
else else
SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_NONE, nullptr); SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_NONE, nullptr);
# elif YASIO_SSL_BACKEND == 2 # elif YASIO_SSL_BACKEND == 2
const char* pers = "yasio_ssl_client";
ssl_ctx_ = new SSL_CTX(); ssl_ctx_ = new SSL_CTX();
::mbedtls_ssl_config_init(&ssl_ctx_->conf); ::mbedtls_ssl_config_init(&ssl_ctx_->conf);
::mbedtls_x509_crt_init(&ssl_ctx_->cacert); ::mbedtls_x509_crt_init(&ssl_ctx_->cacert);
::mbedtls_ctr_drbg_init(&ssl_ctx_->ctr_drbg); ::mbedtls_ctr_drbg_init(&ssl_ctx_->ctr_drbg);
::mbedtls_entropy_init(&ssl_ctx_->entropy); ::mbedtls_entropy_init(&ssl_ctx_->entropy);
int ret = ::mbedtls_ctr_drbg_seed(&ssl_ctx_->ctr_drbg, ::mbedtls_entropy_func, &ssl_ctx_->entropy, (const unsigned char*)pers, strlen(pers)); using namespace cxx17;
auto pers = "yasio_ssl_client"_sv;
int ret = ::mbedtls_ctr_drbg_seed(&ssl_ctx_->ctr_drbg, ::mbedtls_entropy_func, &ssl_ctx_->entropy, (const unsigned char*)pers.data(), pers.length());
if (ret != 0) if (ret != 0)
YASIO_KLOGE("mbedtls_ctr_drbg_seed fail with ret=%d", ret); YASIO_KLOGE("mbedtls_ctr_drbg_seed fail with ret=%d", ret);
@ -1535,6 +1536,12 @@ void io_service::config_ares_name_servers()
std::string nscsv; std::string nscsv;
// list all dns servers for resov problem diagnosis // list all dns servers for resov problem diagnosis
ares_addr_node* name_servers = nullptr; ares_addr_node* name_servers = nullptr;
const char* what = "system";
if (!options_.name_servers_.empty())
{
::ares_set_servers_csv(ares_, options_.name_servers_.c_str());
what = "custom";
}
int status = ::ares_get_servers(ares_, &name_servers); int status = ::ares_get_servers(ares_, &name_servers);
if (status == ARES_SUCCESS) if (status == ARES_SUCCESS)
{ {
@ -1542,14 +1549,14 @@ void io_service::config_ares_name_servers()
endpoint::inaddr_to_csv_nl(name_server->family, &name_server->addr, nscsv); endpoint::inaddr_to_csv_nl(name_server->family, &name_server->addr, nscsv);
if (!nscsv.empty()) // if no valid name server, use predefined fallback dns if (!nscsv.empty()) // if no valid name server, use predefined fallback dns
YASIO_KLOGD("[c-ares] use system dns: %s", nscsv.c_str()); YASIO_KLOGI("[c-ares] use %s dns: %s", what, nscsv.c_str());
else else
{ {
status = ::ares_set_servers_csv(ares_, YASIO_CARES_FALLBACK_DNS); status = ::ares_set_servers_csv(ares_, YASIO_FALLBACK_NAME_SERVERS);
if (status == 0) if (status == 0)
YASIO_KLOGW("[c-ares] set fallback dns: '%s' succeed", YASIO_CARES_FALLBACK_DNS); YASIO_KLOGW("[c-ares] set fallback dns: '%s' succeed", YASIO_FALLBACK_NAME_SERVERS);
else else
YASIO_KLOGE("[c-ares] set fallback dns: '%s' failed, detail: %s", YASIO_CARES_FALLBACK_DNS, ::ares_strerror(status)); YASIO_KLOGE("[c-ares] set fallback dns: '%s' failed, detail: %s", YASIO_FALLBACK_NAME_SERVERS, ::ares_strerror(status));
} }
::ares_free_data(name_servers); ::ares_free_data(name_servers);
} }
@ -2267,6 +2274,12 @@ void io_service::set_option_internal(int opt, va_list ap) // lgtm [cpp/poorly-do
case YOPT_S_DNS_DIRTY: case YOPT_S_DNS_DIRTY:
options_.dns_dirty_ = true; options_.dns_dirty_ = true;
break; break;
#if defined(YASIO_HAVE_CARES)
case YOPT_S_DNS_LIST:
options_.name_servers_ = va_arg(ap, const char*);
options_.dns_dirty_ = true;
break;
#endif
case YOPT_C_UNPACK_PARAMS: { case YOPT_C_UNPACK_PARAMS: {
auto channel = channel_at(static_cast<size_t>(va_arg(ap, int))); auto channel = channel_at(static_cast<size_t>(va_arg(ap, int)));
if (channel) if (channel)

View File

@ -167,6 +167,10 @@ enum
// remarks: you should set this option after your device network changed // remarks: you should set this option after your device network changed
YOPT_S_DNS_DIRTY, YOPT_S_DNS_DIRTY,
// Set custom dns servers
// params: servers: const char*("xxx.xxx.xxx[:port],xxx.xxx.xxx.xxx[:port]")
YOPT_S_DNS_LIST,
// Sets channel length field based frame decode function, native C++ ONLY // Sets channel length field based frame decode function, native C++ ONLY
// params: index:int, func:decode_len_fn_t* // params: index:int, func:decode_len_fn_t*
YOPT_C_LFBFD_FN = 101, YOPT_C_LFBFD_FN = 101,
@ -853,9 +857,14 @@ public:
#if !defined(YASIO_MINIFY_EVENT) #if !defined(YASIO_MINIFY_EVENT)
/* Gets to transport user data when process this event */ /* Gets to transport user data when process this event */
template <typename _Uty = void*> _Uty transport_ud() const { return (_Uty)(uintptr_t)source_ud_; } template <typename _Uty = void*>
_Uty transport_ud() const
{
return (_Uty)(uintptr_t)source_ud_;
}
/* Sets trasnport user data when process this event */ /* Sets trasnport user data when process this event */
template <typename _Uty = void*> void transport_ud(_Uty uval) template <typename _Uty = void*>
void transport_ud(_Uty uval)
{ {
source_ud_ = (void*)(uintptr_t)uval; source_ud_ = (void*)(uintptr_t)uval;
@ -1183,6 +1192,10 @@ private:
// The full path cacert(.pem) file for ssl verifaction // The full path cacert(.pem) file for ssl verifaction
std::string cafile_; std::string cafile_;
#endif #endif
#if defined(YASIO_HAVE_CARES)
std::string name_servers_;
#endif
} options_; } options_;
// The ip stack version supported by localhost // The ip stack version supported by localhost