From d8ac99a0374b528caca66ad8ecb5fb36f6334e77 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 12 Jan 2015 14:58:52 +0100 Subject: cNetwork: Implemented connection shutdown and close. --- src/OSSupport/Network.cpp | 66 +++++++++++++++++++++++++++++++++++++---------- src/OSSupport/Network.h | 10 ++++--- 2 files changed, 59 insertions(+), 17 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Network.cpp b/src/OSSupport/Network.cpp index a34f7ebca..2ef6ace3c 100644 --- a/src/OSSupport/Network.cpp +++ b/src/OSSupport/Network.cpp @@ -87,6 +87,9 @@ public: a_Address and a_AddrLen describe the remote peer that has connected. */ cTCPLinkImpl(evutil_socket_t a_Socket, cCallbacksPtr a_LinkCallbacks, cServerHandleImpl * a_Server, const sockaddr * a_Address, int a_AddrLen); + /** Destroys the LibEvent handle representing the link. */ + ~cTCPLinkImpl(); + /** Queues a connection request to the specified host. a_ConnectCallbacks must be valid. The object must have been constructed by the right constructor (without the Socket param). */ @@ -98,8 +101,8 @@ public: virtual UInt16 GetLocalPort(void) const override { return m_LocalPort; } virtual AString GetRemoteIP(void) const override { return m_RemoteIP; } virtual UInt16 GetRemotePort(void) const override { return m_RemotePort; } + virtual void Shutdown(void) override; virtual void Close(void) override; - virtual void Drop(void) override; protected: @@ -164,6 +167,9 @@ public: cTCPLink::cCallbacksPtr a_LinkCallbacks ); + /** Closes the server, dropping all the connections. */ + ~cServerHandleImpl(); + /** Starts listening on the specified port. Both IPv4 and IPv6 interfaces are used, if possible. */ bool Listen(UInt16 a_Port); @@ -499,6 +505,15 @@ cTCPLinkImpl::cTCPLinkImpl(evutil_socket_t a_Socket, cTCPLink::cCallbacksPtr a_L +cTCPLinkImpl::~cTCPLinkImpl() +{ + bufferevent_free(m_BufferEvent); +} + + + + + /** Schedules the actual connection request. Returns true on success, false on failure. */ bool cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks) @@ -556,20 +571,31 @@ bool cTCPLinkImpl::Send(const void * a_Data, size_t a_Length) -void cTCPLinkImpl::Close(void) +void cTCPLinkImpl::Shutdown(void) { - // TODO - ASSERT(!"cTCPLinkImpl::Close(): Not implemented yet"); + #ifdef _WIN32 + shutdown(bufferevent_getfd(m_BufferEvent), SD_SEND); + #else + shutdown(bufferevent_getfd(m_BufferEvent), SHUT_WR); + #endif + bufferevent_disable(m_BufferEvent, EV_WRITE); } -void cTCPLinkImpl::Drop(void) +void cTCPLinkImpl::Close(void) { - // TODO - ASSERT(!"cTCPLinkImpl::Drop(): Not implemented yet"); + bufferevent_disable(m_BufferEvent, EV_READ | EV_WRITE); + if (m_Server == nullptr) + { + cNetworkSingleton::Get().RemoveLink(this); + } + else + { + m_Server->RemoveLink(this); + } } @@ -736,24 +762,38 @@ cServerHandleImpl::cServerHandleImpl(cNetwork::cListenCallbacksPtr a_ListenCallb +cServerHandleImpl::~cServerHandleImpl() +{ + if (m_ConnListener != nullptr) + { + evconnlistener_free(m_ConnListener); + } + if (m_SecondaryConnListener != nullptr) + { + evconnlistener_free(m_SecondaryConnListener); + } +} + + + + + void cServerHandleImpl::Close(void) { // Stop the listener sockets: - evconnlistener_free(m_ConnListener); - m_ConnListener = nullptr; + evconnlistener_disable(m_ConnListener); if (m_SecondaryConnListener != nullptr) { - evconnlistener_free(m_SecondaryConnListener); - m_SecondaryConnListener = nullptr; + evconnlistener_disable(m_SecondaryConnListener); } m_IsListening = false; - // Close all connections: + // Shutdown all connections: cTCPLinkImplPtrs Conns; std::swap(Conns, m_Connections); for (auto conn: Conns) { - conn->Close(); + conn->Shutdown(); } } diff --git a/src/OSSupport/Network.h b/src/OSSupport/Network.h index 3f60b03a7..11c45b152 100644 --- a/src/OSSupport/Network.h +++ b/src/OSSupport/Network.h @@ -66,12 +66,13 @@ public: virtual UInt16 GetRemotePort(void) const = 0; /** Closes the link gracefully. - The link will keep trying to send the queued data, then it will send the FIN packet. */ - virtual void Close(void) = 0; + The link will send any queued outgoing data, then it will send the FIN packet. + The link will still receive incoming data from remote until the remote closes the connection. */ + virtual void Shutdown(void) = 0; /** Drops the connection without any more processing. Sends the RST packet, queued outgoing and incoming data is lost. */ - virtual void Drop(void) = 0; + virtual void Close(void) = 0; protected: /** Callbacks to be used for the various situations. */ @@ -95,7 +96,8 @@ public: // Force a virtual destructor for all descendants: virtual ~cServerHandle() {} - /** Stops the server, no more incoming connections will be accepted. */ + /** Stops the server, no more incoming connections will be accepted. + All current connections will be shut down (cTCPLink::Shutdown()). */ virtual void Close(void) = 0; /** Returns true if the server has been started correctly and is currently listening for incoming connections. */ -- cgit v1.2.3