Important Update:

- Complete Async resolve:
  - Remove Resolving param from THandle
  - Rename state csResolving -> csPreparing
  - Added handle state csPrepared, to indicated resolve complete
  - Open handle if state = csPrepared
  - Remove Resolve delay (not required since async resolve)
    - remove from JSON config as well
This commit is contained in:
Charl Wentzel
2019-06-10 10:44:51 +02:00
parent bde14a13da
commit 7787da5119
3 changed files with 64 additions and 93 deletions

View File

@@ -79,7 +79,7 @@ CSelectableCore::~CSelectableCore()
while (FirstHandle)
{
// Close active resolve request
if (FirstHandle->Resolving && FirstHandle->ResolveReq) {
if (FirstHandle->ResolveReq) {
if ((Result = gai_cancel( FirstHandle->ResolveReq->Request )) != 0) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Error canceling Host Name resolve [%s:%s] (%s)",
ProcessName, Name, FirstHandle->Name, FirstHandle->HostName, FirstHandle->PortName, gai_strerror(Result) );
@@ -114,7 +114,6 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
short Parity;
short FlowCtrl;
short Queue;
long Delay;
// Call Previous load config
if (!CFunctionCore::Init( FunctionConfig ))
@@ -210,8 +209,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctUDPserver, Address, strlcase(Port), 0, Delay );
SetSocketHandle( Handle, ctUDPserver, Address, strlcase(Port), 0 );
}
else if (!strcasecmp( Type, "UDPclient" ))
{
@@ -222,8 +220,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctUDPclient, Address, strlcase(Port), 0, Delay );
SetSocketHandle( Handle, ctUDPclient, Address, strlcase(Port), 0 );
}
else if (!strcasecmp( Type, "TCPserver" ))
{
@@ -234,9 +231,8 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
Queue = HandleConfig->GetChInt( "Socket/Queue", 2, true );
SetSocketHandle( Handle, ctTCPserver, Address, strlcase(Port), Queue, Delay );
SetSocketHandle( Handle, ctTCPserver, Address, strlcase(Port), Queue );
}
else if (!strcasecmp( Type, "TCPclient" ))
{
@@ -247,8 +243,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)HandleConfig->GetChStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = HandleConfig->GetChInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctTCPclient, Address, strlcase(Port), 0, Delay );
SetSocketHandle( Handle, ctTCPclient, Address, strlcase(Port), 0 );
}
else if (!strcasecmp( Type, "ForkPipe" )) {
Address = (char*)HandleConfig->GetChStr( "Fork/ExecPath", NULL, true ); // Get default value
@@ -285,7 +280,7 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
return false;
// Destroy Resolve request
if (Handle->Resolving && Handle->ResolveReq) {
if (Handle->ResolveReq) {
if ((Result = gai_cancel( Handle->ResolveReq->Request )) != 0) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Error canceling Host Name resolve [%s:%s] (%s)",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(Result) );
@@ -467,7 +462,7 @@ bool CSelectableCore::SetUnixHandle( THandle * Handle, EConnectType Type, const
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, short Queue, long ResolveDelay )
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, short Queue )
{
// Validate
if (!Handle || !HostName || !PortName ||
@@ -478,7 +473,6 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
// Set Type
Handle->Type = Type;
Handle->ResolveDelay = ResolveDelay;
// Clear HostName & Port Name
if (Handle->HostName)
@@ -984,7 +978,7 @@ THandle * CSelectableCore::OpenUNIXremoteSocket( THandle * Handle )
}
//---------------------------------------------------------------------------
bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
bool CSelectableCore::ResolveAddress( THandle * Handle )
{
struct addrinfo * Hints;
TResolveReq * ResolveReq;
@@ -992,7 +986,7 @@ bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
int Result;
// Ignore if busy resolving
if (Handle->Resolving)
if (Handle->State == csPreparing)
return false;
// Check if resolved address available
@@ -1057,17 +1051,9 @@ bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Resolving Host name [%s:%s]...",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName );
// Should address be resolved later during process()
if (DelayResolve) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Delay resolving of Host Name [%s:%s]",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName );
HandleState( Handle, csOpenRequest );
return false;
}
// Resolve Host & Port Names
Handle->Resolving = true;
HandleState( Handle, csPreparing );
if ((Result = getaddrinfo_a( GAI_NOWAIT, &(Handle->ResolveReq->Request), 1, &ResolveEvt )) != 0) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Error resolving Host Name [%s:%s] (%s)",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(Result) );
@@ -1086,9 +1072,6 @@ bool CSelectableCore::DestroyResolveReq( THandle * Handle, bool DestroyResult )
if (!Handle || !Handle->ResolveReq)
return false;
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Destroying resolve request [%s:%s]",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName );
// Destroy
if (DestroyResult) {
if (Handle->ResolveReq->Request->ar_result)
@@ -1103,7 +1086,6 @@ bool CSelectableCore::DestroyResolveReq( THandle * Handle, bool DestroyResult )
// Reset request
Handle->ResolveReq = NULL;
Handle->Resolving = false;
return true;
}
//---------------------------------------------------------------------------
@@ -1149,11 +1131,12 @@ bool CSelectableCore::HandleResolve( THandle * Handle )
// Destroy request
DestroyResolveReq( Handle, false );
HandleState( Handle, csPrepared );
return true;
}
//---------------------------------------------------------------------------
THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle, bool DelayResolve )
THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle )
{
// Validate Handle
if (Handle->Type != ctUDPserver) {
@@ -1161,7 +1144,7 @@ THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle, bool DelayReso
}
// Resolve Host & Port Names
if (!ResolveAddress( Handle, DelayResolve ))
if (!ResolveAddress( Handle ))
return NULL;
// Create socket
@@ -1237,7 +1220,7 @@ THandle * CSelectableCore::OpenUDPremoteSocket( THandle * Handle, char * ClientA
// Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientCount );
*RemoteClient = CreateHandle( ClientName, false );
if (!SetSocketHandle( *RemoteClient, ctUDPremote, ClientAddress, ClientPort, 0, 0 )) {
if (!SetSocketHandle( *RemoteClient, ctUDPremote, ClientAddress, ClientPort, 0 )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - UDP Server failed to configure Remote Client connection (%s)",
ProcessName, Name, Handle->Name, strerror(errno) );
return NULL;
@@ -1269,7 +1252,7 @@ THandle * CSelectableCore::OpenUDPremoteSocket( THandle * Handle, char * ClientA
}
//---------------------------------------------------------------------------
THandle * CSelectableCore::OpenUDPclientSocket( THandle * Handle, bool DelayResolve )
THandle * CSelectableCore::OpenUDPclientSocket( THandle * Handle )
{
// Check state
if (Handle->State == csOpen) {
@@ -1278,7 +1261,7 @@ THandle * CSelectableCore::OpenUDPclientSocket( THandle * Handle, bool DelayReso
}
// Resolve IP Address
if (!ResolveAddress( Handle, DelayResolve ))
if (!ResolveAddress( Handle ))
return NULL;
// Create File descriptor
@@ -1311,7 +1294,7 @@ THandle * CSelectableCore::OpenUDPclientSocket( THandle * Handle, bool DelayReso
}
//---------------------------------------------------------------------------
THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayResolve )
THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle )
{
// Socket options
struct linger ServerLinger_opt;
@@ -1330,7 +1313,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
}
// Resolve Host & Port Names
if (!ResolveAddress( Handle, DelayResolve ))
if (!ResolveAddress( Handle ))
return NULL;
// Create socket
@@ -1476,7 +1459,7 @@ THandle * CSelectableCore::OpenTCPremoteSocket( THandle * Handle )
// Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
*RemoteClient = CreateHandle( ClientName, false );
if (!SetSocketHandle( *RemoteClient, ctTCPremote, ClientAddress, ClientPort, 0, 0 )) {
if (!SetSocketHandle( *RemoteClient, ctTCPremote, ClientAddress, ClientPort, 0 )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - TCP Server failed to configure Remote Client connection (%s)",
ProcessName, Name, Handle->Name, strerror(errno) );
return NULL;
@@ -1529,7 +1512,7 @@ THandle * CSelectableCore::OpenTCPremoteSocket( THandle * Handle )
}
//---------------------------------------------------------------------------
THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayResolve )
THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle )
{
// Socket options
int KeepAlive_opt = 1; // Enable/disable keep alive
@@ -1547,7 +1530,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
if (Handle->State != csWaitingtoOpen)
{
// Resolve IP Address
if (!ResolveAddress( Handle, DelayResolve ))
if (!ResolveAddress( Handle ))
return NULL;
// Create File descriptor
@@ -1638,7 +1621,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
}
//---------------------------------------------------------------------------
int CSelectableCore::Open( THandle * Handle, bool DelayResolve )
int CSelectableCore::Open( THandle * Handle )
{
THandle * NewHandle = NULL;
@@ -1665,16 +1648,16 @@ int CSelectableCore::Open( THandle * Handle, bool DelayResolve )
NewHandle = OpenUNIXclientSocket( Handle );
break;
case ctUDPserver :
NewHandle = OpenUDPserverSocket( Handle, DelayResolve );
NewHandle = OpenUDPserverSocket( Handle );
break;
case ctUDPclient :
NewHandle = OpenUDPclientSocket( Handle, DelayResolve );
NewHandle = OpenUDPclientSocket( Handle );
break;
case ctTCPserver :
NewHandle = OpenTCPserverSocket( Handle, DelayResolve );
NewHandle = OpenTCPserverSocket( Handle );
break;
case ctTCPclient :
NewHandle = OpenTCPclientSocket( Handle, DelayResolve );
NewHandle = OpenTCPclientSocket( Handle );
break;
default:
NewHandle = NULL;
@@ -1880,7 +1863,7 @@ bool CSelectableCore::Read( THandle * Handle )
if (Handle->Type == ctTCPremote) {
OpenTCPremoteSocket( Handle );
} else if (Handle->Type == ctTCPclient) {
OpenTCPclientSocket( Handle, true );
OpenTCPclientSocket( Handle );
} else if (Handle->Type == ctUNIXremote) {
OpenUNIXremoteSocket( Handle );
} else if (Handle->Type == ctUNIXclient) {
@@ -2042,7 +2025,7 @@ bool CSelectableCore::Write( THandle * Handle )
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
{
// Attempt to re-open port
Open( Handle, true );
Open( Handle );
}
}
@@ -2056,7 +2039,7 @@ bool CSelectableCore::Write( THandle * Handle )
if (Handle->Type == ctTCPremote) {
OpenTCPremoteSocket( Handle );
} else if (Handle->Type == ctTCPclient) {
OpenTCPclientSocket( Handle, true );
OpenTCPclientSocket( Handle );
} else if (Handle->Type == ctUNIXremote) {
OpenUNIXremoteSocket( Handle );
} else if (Handle->Type == ctUNIXclient) {
@@ -2207,11 +2190,11 @@ int CSelectableCore::OutputHandle( THandle * Handle, const char * Data, int Len
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
{
// Complete opening process
Open( Handle, true );
Open( Handle );
// Check if Handle is open
if (Handle->State == csOpenRequest) {
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Handle '%s' - Input rejected, Request to resolve (auto-managed) Handle",
if (Handle->State == csPreparing) {
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Handle '%s' - Input rejected, Resolving (auto-managed) Handle",
ProcessName, Name, Handle->Name );
return 0;
}
@@ -2353,16 +2336,14 @@ bool CSelectableCore::Process()
while (Handle)
{
// Auto manage handles
if ((Handle->State == csOpenRequest)) {
// Resolve then open socket
if (Timeout( Handle->LastAction, Handle->ResolveDelay )) {
Open( Handle, false );
}
if (Handle->State == csPrepared) {
// Proceed to open
Open( Handle );
}
else if (((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent) ) {
else if ((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent) {
// Try to re-open port after delay
if (Timeout( Handle->LastAction, Handle->ReopenDelay )) {
Open( Handle, false );
Open( Handle );
}
}