Commit 41547a86 authored by Joseph Noir's avatar Joseph Noir

Fix disconnect issue on Windows

WSAGetLastError should be invoked right after Windows sockets
functions.
parent 3ecdb1c9
...@@ -339,8 +339,6 @@ namespace network { ...@@ -339,8 +339,6 @@ namespace network {
presult = ::poll(pollset_.data(), presult = ::poll(pollset_.data(),
static_cast<nfds_t>(pollset_.size()), block ? -1 : 0); static_cast<nfds_t>(pollset_.size()), block ? -1 : 0);
# endif # endif
CAF_LOG_DEBUG("poll() on" << pollset_.size()
<< "sockets reported" << presult << "event(s)");
if (presult < 0) { if (presult < 0) {
switch (last_socket_error()) { switch (last_socket_error()) {
case EINTR: { case EINTR: {
...@@ -362,6 +360,8 @@ namespace network { ...@@ -362,6 +360,8 @@ namespace network {
} }
continue; // rinse and repeat continue; // rinse and repeat
} }
CAF_LOG_DEBUG("poll() on" << pollset_.size()
<< "sockets reported" << presult << "event(s)");
if (presult == 0) if (presult == 0)
return false; return false;
// scan pollset for events first, because we might alter pollset_ // scan pollset for events first, because we might alter pollset_
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <cstring> #include <cstring>
#include "caf/io/network/native_socket.hpp"
#include "caf/logger.hpp" #include "caf/logger.hpp"
#ifdef CAF_WINDOWS #ifdef CAF_WINDOWS
...@@ -34,6 +35,7 @@ using caf::io::network::rw_state; ...@@ -34,6 +35,7 @@ using caf::io::network::rw_state;
using caf::io::network::native_socket; using caf::io::network::native_socket;
using caf::io::network::socket_size_type; using caf::io::network::socket_size_type;
using caf::io::network::no_sigpipe_io_flag; using caf::io::network::no_sigpipe_io_flag;
using caf::io::network::last_socket_error_as_string;
namespace caf { namespace caf {
namespace policy { namespace policy {
...@@ -43,11 +45,15 @@ rw_state tcp::read_some(size_t& result, native_socket fd, void* buf, ...@@ -43,11 +45,15 @@ rw_state tcp::read_some(size_t& result, native_socket fd, void* buf,
CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len)); CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len));
auto sres = ::recv(fd, reinterpret_cast<io::network::socket_recv_ptr>(buf), auto sres = ::recv(fd, reinterpret_cast<io::network::socket_recv_ptr>(buf),
len, no_sigpipe_io_flag); len, no_sigpipe_io_flag);
CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres)); if (is_error(sres, true)) {
if (is_error(sres, true) || sres == 0) { CAF_LOG_ERROR("recv failed:" << last_socket_error_as_string());
return rw_state::failure;
} else if (sres == 0) {
// recv returns 0 when the peer has performed an orderly shutdown // recv returns 0 when the peer has performed an orderly shutdown
CAF_LOG_DEBUG("peer performed orderly shutdown" << CAF_ARG(fd));
return rw_state::failure; return rw_state::failure;
} }
CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres));
result = (sres > 0) ? static_cast<size_t>(sres) : 0; result = (sres > 0) ? static_cast<size_t>(sres) : 0;
return rw_state::success; return rw_state::success;
} }
...@@ -57,9 +63,11 @@ rw_state tcp::write_some(size_t& result, native_socket fd, const void* buf, ...@@ -57,9 +63,11 @@ rw_state tcp::write_some(size_t& result, native_socket fd, const void* buf,
CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len)); CAF_LOG_TRACE(CAF_ARG(fd) << CAF_ARG(len));
auto sres = ::send(fd, reinterpret_cast<io::network::socket_send_ptr>(buf), auto sres = ::send(fd, reinterpret_cast<io::network::socket_send_ptr>(buf),
len, no_sigpipe_io_flag); len, no_sigpipe_io_flag);
CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres)); if (is_error(sres, true)) {
if (is_error(sres, true)) CAF_LOG_ERROR("send failed:" << last_socket_error_as_string());
return rw_state::failure; return rw_state::failure;
}
CAF_LOG_DEBUG(CAF_ARG(len) << CAF_ARG(fd) << CAF_ARG(sres));
result = (sres > 0) ? static_cast<size_t>(sres) : 0; result = (sres > 0) ? static_cast<size_t>(sres) : 0;
return rw_state::success; return rw_state::success;
} }
...@@ -72,14 +80,15 @@ bool tcp::try_accept(native_socket& result, native_socket fd) { ...@@ -72,14 +80,15 @@ bool tcp::try_accept(native_socket& result, native_socket fd) {
socket_size_type addrlen = sizeof(addr); socket_size_type addrlen = sizeof(addr);
result = ::accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen); result = ::accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
// note accept4 is better to avoid races in setting CLOEXEC (but not posix) // note accept4 is better to avoid races in setting CLOEXEC (but not posix)
child_process_inherit(result, false);
CAF_LOG_DEBUG(CAF_ARG(fd) << CAF_ARG(result));
if (result == invalid_native_socket) { if (result == invalid_native_socket) {
auto err = last_socket_error(); auto err = last_socket_error();
if (!would_block_or_temporarily_unavailable(err)) { if (!would_block_or_temporarily_unavailable(err)) {
CAF_LOG_ERROR("accept failed:" << last_socket_error_as_string());
return false; return false;
} }
} }
child_process_inherit(result, false);
CAF_LOG_DEBUG(CAF_ARG(fd) << CAF_ARG(result));
return true; return true;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "caf/policy/udp.hpp" #include "caf/policy/udp.hpp"
#include "caf/io/network/native_socket.hpp"
#include "caf/logger.hpp" #include "caf/logger.hpp"
#ifdef CAF_WINDOWS #ifdef CAF_WINDOWS
...@@ -32,6 +33,7 @@ using caf::io::network::ip_endpoint; ...@@ -32,6 +33,7 @@ using caf::io::network::ip_endpoint;
using caf::io::network::native_socket; using caf::io::network::native_socket;
using caf::io::network::signed_size_type; using caf::io::network::signed_size_type;
using caf::io::network::socket_size_type; using caf::io::network::socket_size_type;
using caf::io::network::last_socket_error_as_string;
namespace caf { namespace caf {
namespace policy { namespace policy {
...@@ -44,7 +46,7 @@ bool udp::read_datagram(size_t& result, native_socket fd, void* buf, ...@@ -44,7 +46,7 @@ bool udp::read_datagram(size_t& result, native_socket fd, void* buf,
auto sres = ::recvfrom(fd, static_cast<io::network::socket_recv_ptr>(buf), auto sres = ::recvfrom(fd, static_cast<io::network::socket_recv_ptr>(buf),
buf_len, 0, ep.address(), &len); buf_len, 0, ep.address(), &len);
if (is_error(sres, true)) { if (is_error(sres, true)) {
CAF_LOG_ERROR("recvfrom returned" << CAF_ARG(sres)); CAF_LOG_ERROR("recvfrom failed:" << last_socket_error_as_string());
return false; return false;
} }
if (sres == 0) if (sres == 0)
...@@ -64,7 +66,7 @@ bool udp::write_datagram(size_t& result, native_socket fd, void* buf, ...@@ -64,7 +66,7 @@ bool udp::write_datagram(size_t& result, native_socket fd, void* buf,
auto sres = ::sendto(fd, reinterpret_cast<io::network::socket_send_ptr>(buf), auto sres = ::sendto(fd, reinterpret_cast<io::network::socket_send_ptr>(buf),
buf_len, 0, ep.caddress(), len); buf_len, 0, ep.caddress(), len);
if (is_error(sres, true)) { if (is_error(sres, true)) {
CAF_LOG_ERROR("sendto returned" << CAF_ARG(sres)); CAF_LOG_ERROR("sendto failed:" << last_socket_error_as_string());
return false; return false;
} }
result = (sres > 0) ? static_cast<size_t>(sres) : 0; result = (sres > 0) ? static_cast<size_t>(sres) : 0;
......
...@@ -81,13 +81,15 @@ struct ssl_policy { ...@@ -81,13 +81,15 @@ struct ssl_policy {
caf::io::network::socket_size_type addrlen = sizeof(addr); caf::io::network::socket_size_type addrlen = sizeof(addr);
result = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen); result = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
// note accept4 is better to avoid races in setting CLOEXEC (but not posix) // note accept4 is better to avoid races in setting CLOEXEC (but not posix)
io::network::child_process_inherit(result, false);
CAF_LOG_DEBUG(CAF_ARG(fd) << CAF_ARG(result));
if (result == io::network::invalid_native_socket) { if (result == io::network::invalid_native_socket) {
auto err = io::network::last_socket_error(); auto err = io::network::last_socket_error();
if (!io::network::would_block_or_temporarily_unavailable(err)) if (!io::network::would_block_or_temporarily_unavailable(err))
CAF_LOG_ERROR("accept failed:"
<< io::network::last_socket_error_as_string());
return false; return false;
} }
io::network::child_process_inherit(result, false);
CAF_LOG_DEBUG(CAF_ARG(fd) << CAF_ARG(result));
return session_->try_accept(result); return session_->try_accept(result);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment