简体   繁体   English

套接字已接受,但m_socket.remote_endpoint提高传输端点未连接

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

Code: 码:

Listener.hpp: Listener.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();
}

Socket.cpp: Socket.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;
}

Is this related to TCP attack? 这与TCP攻击有关吗?

EDIT: gdb: 编辑: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

EDIT: NetworkThread.hpp: 编辑: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;
}

The problem is totally different: 问题完全不同:

In your code: 在您的代码中:

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.
}

Bottom line: OnAccept() needs to receive the socket pointer by value, and it needs to transfer or store this shared pointer somehow. 底线: OnAccept()需要按值接收套接字指针,并且需要以某种方式传输或存储此共享指针。 This is usually done by passing the shared_ptr to BeginReceive() BY VALUE . 通常,这是通过将shared_ptr传递给BeginReceive() BY VALUE来完成的 BeginReceive() must then take the responsibility to keep the socket pointer alive until the connection dies, this, it usually does that by passing the pointer back to itself, either as a parameter, or as a lambda capture, always by value. 然后,BeginReceive()必须负责保持套接字指针处于活动状态,直到连接终止,这通常是通过始终按值将指针作为参数或lambda捕获传递回自身来实现的。

The easiest way to fix your code is to move the call to StartAsyncRead() to OnAccept() , since there is a convenient copy of a shared_ptr of the socket there. 修复代码的最简单方法是将对StartAsyncRead()的调用移至OnAccept() ,因为那里有套接字的shared_ptr的便捷副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM