接受套接字,但m_socket.远程终结点引发 传输终结点未连接

socket accepted but m_socket.remote_endpoint raise Transport endpoint is not connected

本文关键字:结点 传输 连接 程终 套接字 socket      更新时间:2023-10-16

代码:

听众.hpp:

template <typename SocketType>
void Listener<SocketType>::BeginAccept()
{
auto worker = SelectWorker();
auto socket = worker->CreateSocket();
m_acceptor->async_accept(socket->GetAsioSocket(),
[this, worker, socket] (const boost::system::error_code &ec)
{
this->OnAccept(worker, socket, ec);
});
}
template <typename SocketType>
void Listener<SocketType>::OnAccept(NetworkThread<SocketType> *worker, std::shared_ptr<SocketType> const& socket, const boost::system::error_code &ec)
{
// an error has occurred
if (ec)
worker->RemoveSocket(socket.get());
else
socket->Open();
BeginAccept();
}

插座.cpp:

bool Socket::Open()
{
try
{
const_cast<std::string &>(m_address) = m_socket.remote_endpoint().address().to_string();
const_cast<std::string &>(m_remoteEndpoint) = boost::lexical_cast<std::string>(m_socket.remote_endpoint());
}
catch (boost::system::error_code& error)
{
sLog.outInfo("Socket::Open() failed to get remote address.  Error: %s", error.message().c_str());
return false;
}
catch (const std::exception& error)
{
sLog.outInfo("Socket::Open() failed(with std::exception) to get remote address.  Error: %s", error.what());
return false;
}
catch (...)
{
sLog.outError("Socket::Open() failed to get remote address.  Other error");
return false;
}
m_outBuffer.reset(new PacketBuffer);
m_secondaryOutBuffer.reset(new PacketBuffer);
m_inBuffer.reset(new PacketBuffer);
StartAsyncRead();
return true;
}

这与TCP攻击有关吗?

编辑: GDB:

(gdb) p m_socket
$1 = {<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >> = {<boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp>, true>> = {
implementation = {<boost::asio::detail::reactive_socket_service_base::base_implementation_type> = {socket_ = 21, state_ = 80 'P', reactor_data_ = 0x7ffff0005120}, protocol_ = {family_ = 2}}, service_ = 0x7f2b30}, <boost::asio::socket_base> = {
static message_peek = 2, static message_out_of_band = 1, static message_do_not_route = 4, static message_end_of_record = 128, static max_connections = 128}, <No data fields>}, <No data fields>}
(gdb) p m_socket.is_open()
$2 = true
(gdb) bt
#0  MaNGOS::Socket::Open (this=0x7ffff0003c40) at /home/ubuntu/MoltenCore/MoltenCore/src/shared/Network/Socket.cpp:52
#1  0x00000000004fbff1 in MaNGOS::Listener<AuthSocket>::OnAccept (this=0x7fffffffe6c0, worker=0x8041e0, socket=std::shared_ptr (count 2, weak 1) 0x7ffff0003c40, ec=...) at /home/ubuntu/MoltenCore/MoltenCore/src/shared/Network/Listener.hpp:121
#2  0x00000000004fa030 in MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}::operator()(boost::system::error_code const&) const (__closure=0x7ffff4ec8be0, ec=...)
at /home/ubuntu/MoltenCore/MoltenCore/src/shared/Network/Listener.hpp:110
#3  0x0000000000502a2d in boost::asio::detail::binder1<MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}, boost::system::error_code>::operator()() (this=0x7ffff4ec8be0) at /usr/include/boost/asio/detail/bind_handler.hpp:47
#4  0x00000000005020c3 in boost::asio::asio_handler_invoke<boost::asio::detail::binder1<MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}, boost::system::error_code> >(boost::asio::detail::binder1<MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}, boost::system::error_code>&, ...) (function=...) at /usr/include/boost/asio/handler_invoke_hook.hpp:69
#5  0x00000000005014b8 in boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}, boost::system::error_code>, {lambda(boost::system::error_code const&)#1}>(boost::asio::detail::binder1<MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}, boost::system::error_code>&, {lambda(boost::system::error_code const&)#1}&) (function=..., context=...)
at /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#6  0x0000000000500886 in boost::asio::detail::reactive_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ip::tcp, MaNGOS::Listener<AuthSocket>::BeginAccept()::{lambda(boost::system::error_code const&)#1}>::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (owner=0x8084d0, base=0x804910) at /usr/include/boost/asio/detail/reactive_socket_accept_op.hpp:123
#7  0x00000000004f0300 in boost::asio::detail::task_io_service_operation::complete (this=0x804910, owner=..., ec=..., bytes_transferred=0) at /usr/include/boost/asio/detail/task_io_service_operation.hpp:38
#8  0x00000000004f1d55 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete (owner=0x8084d0, base=0x804140, ec=..., bytes_transferred=1) at /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:651
#9  0x00000000004f0300 in boost::asio::detail::task_io_service_operation::complete (this=0x804140, owner=..., ec=..., bytes_transferred=1) at /usr/include/boost/asio/detail/task_io_service_operation.hpp:38
#10 0x00000000004f2823 in boost::asio::detail::task_io_service::do_run_one (this=0x8084d0, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:372
#11 0x00000000004f23a1 in boost::asio::detail::task_io_service::run (this=0x8084d0, ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:149
#12 0x00000000004f2abc in boost::asio::io_service::run (this=0x7ef540) at /usr/include/boost/asio/impl/io_service.ipp:59
#13 0x00000000004f7c89 in MaNGOS::Listener<AuthSocket>::Listener(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)::{lambda()#1}::operator()() const () at /home/ubuntu/MoltenCore/MoltenCore/src/shared/Network/Listener.hpp:84
#14 0x0000000000505624 in std::_Bind_simple<MaNGOS::Listener<AuthSocket>::Listener(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (this=0x8049c8)
at /usr/include/c++/5/functional:1531
#15 0x0000000000504f38 in std::_Bind_simple<MaNGOS::Listener<AuthSocket>::Listener(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)::{lambda()#1} ()>::operator()() (this=0x8049c8) at /usr/include/c++/5/functional:1520
#16 0x0000000000504416 in std::thread::_Impl<std::_Bind_simple<MaNGOS::Listener<AuthSocket>::Listener(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)::{lambda()#1} ()> >::_M_run() (this=0x8049b0) at /usr/include/c++/5/thread:115
#17 0x00007ffff6c98c80 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#18 0x00007ffff7bc16ba in start_thread (arg=0x7ffff4ec9700) at pthread_create.c:333
#19 0x00007ffff63fe82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

编辑: NetworkThread.hpp:

template <typename SocketType>
class NetworkThread
{
private:
boost::asio::io_service m_service;
std::mutex m_socketLock;
std::unordered_set<std::shared_ptr<SocketType>> m_sockets;
// note that the work member *must* be declared after the service member for the work constructor to function correctly
std::unique_ptr<boost::asio::io_service::work> m_work;
std::thread m_serviceThread;
public:
NetworkThread() : m_work(new boost::asio::io_service::work(m_service))
{
m_serviceThread = std::thread([this] { boost::system::error_code ec; this->m_service.run(ec); });
}
~NetworkThread()
{
// Allow io_service::run() to exit.
m_work.reset();
m_service.stop();
m_serviceThread.join();
// attempt to gracefully close any open connections
for (auto i = m_sockets.begin(); i != m_sockets.end();)
{
auto const current = i;
++i;
if (!(*current)->IsClosed())
(*current)->Close();
}
}
size_t Size() const { return m_sockets.size(); }
std::shared_ptr<SocketType> CreateSocket();
void RemoveSocket(Socket *socket)
{
std::lock_guard<std::mutex> guard(m_socketLock);
m_sockets.erase(socket->shared<SocketType>());
}
};
template <typename SocketType>
std::shared_ptr<SocketType> NetworkThread<SocketType>::CreateSocket()
{
std::lock_guard<std::mutex> guard(m_socketLock);
auto const i = m_sockets.emplace(std::make_shared<SocketType>(m_service, [this] (Socket *socket) { this->RemoveSocket(socket); }));
return *i.first;
}

问题完全不同:

在您的代码中:

template <typename SocketType>
void Listener<SocketType>::OnAccept(
NetworkThread<SocketType> *worker, 
std::shared_ptr<SocketType> const& socket, 
const boost::system::error_code &ec )
{
// at this point, socket has 1 reference count, held by the lambda 
// in BeginAccept, its reference count cannot increase, since it's 
// constant.  
// ...     
BeginAccept(); // this creates a new, distinct  instance of the lambda 
// fuinction object in BeginAccept.
// when we exit, constrol is given back to calling lambda in BeginAccept
// its destructor happily deletes the socket, since its reference count
// is still only 1.
}

底线:OnAccept(( 需要按值接收套接字指针,并且它需要以某种方式传输或存储此共享指针。 这通常是完成的 通过将shared_ptr传递给 BeginReceive((BY VALUE。然后,BeginReceive(( 必须负责保持套接字指针处于活动状态,直到连接死亡,这通常通过将指针作为参数或作为 lambda 捕获(始终按值(传递回自身来做到这一点。

修复代码的最简单方法是将调用移动到StartAsyncRead()OnAccept(),因为那里有一个方便的套接字shared_ptr副本。