cNetwork: Refactored cTCPLinkImpl::Connect into a factory.
This commit is contained in:
parent
6f29cfe084
commit
728a624e48
@ -18,6 +18,16 @@
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cServerHandleImpl;
|
||||
class cTCPLinkImpl;
|
||||
typedef SharedPtr<cTCPLinkImpl> cTCPLinkImplPtr;
|
||||
typedef std::vector<cTCPLinkImplPtr> cTCPLinkImplPtrs;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Class definitions:
|
||||
|
||||
@ -63,13 +73,6 @@ typedef std::vector<cIPLookupPtr> cIPLookupPtrs;
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cServerHandleImpl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Implements the cTCPLink details so that it can represent the single connection between two endpoints. */
|
||||
class cTCPLinkImpl:
|
||||
public cTCPLink
|
||||
@ -78,11 +81,6 @@ class cTCPLinkImpl:
|
||||
friend class cServerHandleImpl;
|
||||
|
||||
public:
|
||||
/** Creates a new link to be queued to connect to a specified host:port.
|
||||
Used for outgoing connections created using cNetwork::Connect().
|
||||
Call Connect() first, before using the link. */
|
||||
cTCPLinkImpl(const cCallbacksPtr a_LinkCallbacks);
|
||||
|
||||
/** Creates a new link based on the given socket.
|
||||
Used for connections accepted in a server using cNetwork::Listen().
|
||||
a_Address and a_AddrLen describe the remote peer that has connected. */
|
||||
@ -93,8 +91,8 @@ public:
|
||||
|
||||
/** 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). */
|
||||
bool Connect(const AString & a_Host, UInt16 a_Port, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks);
|
||||
Returns a link that has the connection request queued, or NULL for failure. */
|
||||
static cTCPLinkImplPtr Connect(const AString & a_Host, UInt16 a_Port, cTCPLink::cCallbacksPtr a_LinkCallbacks, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks);
|
||||
|
||||
// cTCPLink overrides:
|
||||
virtual bool Send(const void * a_Data, size_t a_Length) override;
|
||||
@ -131,6 +129,11 @@ protected:
|
||||
UInt16 m_RemotePort;
|
||||
|
||||
|
||||
/** Creates a new link to be queued to connect to a specified host:port.
|
||||
Used for outgoing connections created using cNetwork::Connect().
|
||||
To be used only by the Connect() factory function. */
|
||||
cTCPLinkImpl(const cCallbacksPtr a_LinkCallbacks);
|
||||
|
||||
/** Callback that LibEvent calls when there's data available from the remote peer. */
|
||||
static void ReadCallback(bufferevent * a_BufferEvent, void * a_Self);
|
||||
|
||||
@ -146,8 +149,6 @@ protected:
|
||||
/** Updates m_RemoteIP and m_RemotePort based on the metadata read from the socket. */
|
||||
void UpdateRemoteAddress(void);
|
||||
};
|
||||
typedef SharedPtr<cTCPLinkImpl> cTCPLinkImplPtr;
|
||||
typedef std::vector<cTCPLinkImplPtr> cTCPLinkImplPtrs;
|
||||
|
||||
|
||||
|
||||
@ -314,6 +315,10 @@ protected:
|
||||
Used by the underlying lookup implementation when the lookup is finished. */
|
||||
void RemoveIPLookup(const cIPLookup * a_IPLookup);
|
||||
|
||||
/** Adds the specified link to m_Connections.
|
||||
Used by the underlying link implementation when a new link is created. */
|
||||
void AddLink(cTCPLinkImplPtr a_Link);
|
||||
|
||||
/** Removes the specified link from m_Connections.
|
||||
Used by the underlying link implementation when the link is closed / errored. */
|
||||
void RemoveLink(const cTCPLinkImpl * a_Link);
|
||||
@ -526,13 +531,15 @@ cTCPLinkImpl::~cTCPLinkImpl()
|
||||
|
||||
|
||||
|
||||
bool cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks)
|
||||
cTCPLinkImplPtr cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cTCPLink::cCallbacksPtr a_LinkCallbacks, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks)
|
||||
{
|
||||
ASSERT(bufferevent_getfd(m_BufferEvent) == -1); // Did you create this object using the right constructor (the one without the Socket param)?
|
||||
ASSERT(m_Server == nullptr);
|
||||
ASSERT(a_LinkCallbacks != nullptr);
|
||||
ASSERT(a_ConnectCallbacks != nullptr);
|
||||
|
||||
m_ConnectCallbacks = a_ConnectCallbacks;
|
||||
// Create a new link:
|
||||
cTCPLinkImplPtr res{new cTCPLinkImpl(a_LinkCallbacks)}; // Cannot use std::make_shared here, constructor is not accessible
|
||||
res->m_ConnectCallbacks = a_ConnectCallbacks;
|
||||
cNetworkSingleton::Get().AddLink(res);
|
||||
|
||||
// If a_Host is an IP address, schedule a connection immediately:
|
||||
sockaddr_storage sa;
|
||||
@ -549,23 +556,26 @@ bool cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cNetwork::cCon
|
||||
reinterpret_cast<sockaddr_in *>(&sa)->sin_port = htons(a_Port);
|
||||
}
|
||||
|
||||
if (bufferevent_socket_connect(m_BufferEvent, reinterpret_cast<sockaddr *>(&sa), salen) == 0)
|
||||
// Queue the connect request:
|
||||
if (bufferevent_socket_connect(res->m_BufferEvent, reinterpret_cast<sockaddr *>(&sa), salen) == 0)
|
||||
{
|
||||
// Success
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
// Failure
|
||||
return false;
|
||||
cNetworkSingleton::Get().RemoveLink(res.get());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// a_Host is a hostname, connect after a lookup:
|
||||
if (bufferevent_socket_connect_hostname(m_BufferEvent, cNetworkSingleton::Get().m_DNSBase, AF_UNSPEC, a_Host.c_str(), a_Port) == 0)
|
||||
if (bufferevent_socket_connect_hostname(res->m_BufferEvent, cNetworkSingleton::Get().m_DNSBase, AF_UNSPEC, a_Host.c_str(), a_Port) == 0)
|
||||
{
|
||||
// Success
|
||||
return true;
|
||||
return res;
|
||||
}
|
||||
// Failure
|
||||
return false;
|
||||
cNetworkSingleton::Get().RemoveLink(res.get());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -1097,21 +1107,8 @@ bool cNetworkSingleton::Connect(
|
||||
)
|
||||
{
|
||||
// Add a connection request to the queue:
|
||||
cTCPLinkImplPtr ConnRequest = std::make_shared<cTCPLinkImpl>(a_LinkCallbacks);
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
m_Connections.push_back(ConnRequest);
|
||||
} // Lock(m_CS)
|
||||
|
||||
// Queue the connection:
|
||||
if (!ConnRequest->Connect(a_Host, a_Port, a_ConnectCallbacks))
|
||||
{
|
||||
RemoveLink(ConnRequest.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything successful, return success:
|
||||
return true;
|
||||
cTCPLinkImplPtr Conn = cTCPLinkImpl::Connect(a_Host, a_Port, a_LinkCallbacks, a_ConnectCallbacks);
|
||||
return (Conn != nullptr);
|
||||
}
|
||||
|
||||
|
||||
@ -1241,6 +1238,16 @@ void cNetworkSingleton::RemoveIPLookup(const cIPLookup * a_IPLookup)
|
||||
|
||||
|
||||
|
||||
void cNetworkSingleton::AddLink(cTCPLinkImplPtr a_Link)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
m_Connections.push_back(a_Link);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cNetworkSingleton::RemoveLink(const cTCPLinkImpl * a_Link)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
|
Loading…
Reference in New Issue
Block a user