Sync yasio to latest

This commit is contained in:
halx99 2021-11-04 16:06:18 +08:00
parent f578dacae9
commit 91820ed458
3 changed files with 45 additions and 12 deletions

View File

@ -104,6 +104,19 @@ SOFTWARE.
# define YASIO__UDP_KROUTE 1
#endif
// Tests whether current OS is BSD-like system
#if YASIO__HAS_CXX17
# if defined(__unix__) || __has_include(<sys/param.h>)
# include <sys/param.h>
# endif
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(BSD)
# define YASIO__OS_BSD 1
#else
# define YASIO__OS_BSD 0
#endif
// Test whether sockaddr has member 'sa_len'
// see also: https://github.com/freebsd/freebsd-src/blob/main/sys/sys/socket.h#L329
#if defined(__linux__) || defined(_WIN32)
@ -166,6 +179,14 @@ SOFTWARE.
# define yasio__unlikely(exp) (!!(exp))
#endif
#ifdef __GNUC__
# define YASIO__UNUSED __attribute__((unused))
#else
# define YASIO__UNUSED
#endif
#define YASIO__UNUSED_PARAM(param) (void)param
#define YASIO__STD ::std::
#if YASIO__HAS_CXX14

View File

@ -596,22 +596,32 @@ int xxsocket::connect_n(socket_native_type s, const endpoint& ep)
int xxsocket::disconnect() const { return xxsocket::disconnect(this->fd); }
int xxsocket::disconnect(socket_native_type s)
{
ip::endpoint addr_unspec = xxsocket::local_endpoint(s);
auto addr_len = addr_unspec.len();
addr_unspec.zeroset();
addr_unspec.af(AF_UNSPEC);
sockaddr addr_unspec{0};
addr_unspec.sa_family = AF_UNSPEC;
#if defined(_WIN32)
return ::connect(s, &addr_unspec, addr_len);
return ::connect(s, &addr_unspec, sizeof(addr_unspec));
#else
int ret, error;
for (;;)
{
ret = ::connect(s, &addr_unspec, addr_len);
ret = ::connect(s, &addr_unspec, sizeof(addr_unspec));
if (ret == 0)
return 0;
if ((error = xxsocket::get_last_errno()) == EINTR)
continue;
return error == EAFNOSUPPORT ? 0 : -1;
# if YASIO__OS_BSD
/*
* From kernel source code of FreeBSD,NetBSD,OpenBSD,etc.
* The udp socket will be success disconnected by kernel function: `sodisconnect(upic_socket.c)`, then in the kernel, will continue try to
* connect with new sockaddr, but will failed with follow errno:
* a. EINVAL: addrlen mismatch
* b. ENOSUPPORT: family mismatch
* So, we just simply ignore them for the disconnect behavior.
*/
return (error == EAFNOSUPPORT || error == EINVAL) ? 0 : -1;
# else
return ret;
# endif
}
#endif
}

View File

@ -639,13 +639,15 @@ void io_transport_udp::disconnect()
auto ifaddr = this->socket_->local_endpoint();
#endif
int retval = this->socket_->disconnect();
#if defined(__linux__)
if (retval == 0)
{
#if defined(__linux__) // Because some of linux will unbind when disconnect succeed, so try to rebind
{ // Because some of linux will unbind when disconnect succeed, so try to rebind
ifaddr.ip(ctx_->local_host_.empty() ? YASIO_ADDR_ANY(ifaddr.af()) : ctx_->local_host_.c_str());
this->socket_->bind(ifaddr);
#endif
}
#else
YASIO__UNUSED_PARAM(retval);
#endif
connected_ = false;
set_primitives();
}
@ -2168,9 +2170,9 @@ void io_service::start_resolve(io_channel* ctx)
#else
ares_addrinfo_hints hint;
memset(&hint, 0x0, sizeof(hint));
hint.ai_family = local_address_family();
hint.ai_family = local_address_family();
char sport[sizeof "65535"] = {'\0'};
const char* service = nullptr;
const char* service = nullptr;
if (ctx->remote_port_ > 0)
{
sprintf(sport, "%u", ctx->remote_port_); // It's enough for unsigned short, so use sprintf ok.