Important Updates:

- FunctionCore:
  - Output() returns largest no of bytes written to linked input
- SelectableCore:
  - Auto-manage:
    - Add AutoManage param -> Persistent
    - Will automatic open port if written to when Auto-Manage enabled
    - Will keep port open (re-open if closed) if Persistent = true
  - DNS resolve:
    - Set AddressFailed if port could not open/bind
    - Only use next resolved address if current address failed
This commit is contained in:
Charl Wentzel
2017-11-18 17:06:32 +02:00
parent abba077ed0
commit 7ef3d71af9
3 changed files with 74 additions and 14 deletions

View File

@@ -129,6 +129,7 @@ bool CSelectableCore::LoadConfigData()
// Set Auto Mange
SetAutoManage( Handle, DataTree->GetBool( TempMember, "AutoManage/Enabled", true, true ),
DataTree->GetBool( TempMember, "AutoManage/Persistent", false, true ),
DataTree->GetInt( TempMember, "AutoManage/ReopenDelay", 2000, true ) );
// Input buffer
@@ -377,7 +378,7 @@ bool CSelectableCore::SetCallback( THandle * Handle, EConnectState pState, FHand
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, int ReopenDelay )
bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, bool Persistent, int ReopenDelay )
{
// Validate
if (!Handle) {
@@ -386,6 +387,7 @@ bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, int Reop
// Set params
Handle->AutoManage = AutoManage;
Handle->Persistent = Persistent;
Handle->ReopenDelay = ReopenDelay;
return true;
}
@@ -574,13 +576,23 @@ bool CSelectableCore::ResolveAddress( THandle * Handle )
struct addrinfo hints;
int result;
// Check if more addresses
// Check if resolved address available
if (Handle->AddressInfo)
{
// Return if address still valid
if (!Handle->AddressFailed)
return true;
// Get next address
Handle->AddressInfo = Handle->AddressInfo->ai_next;
Handle->AddressFailed = false;
}
// Dismiss invalid "0.0.0.0" address
if (Handle->AddressInfo && !strcmp( inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr), "0.0.0.0" ))
Handle->AddressInfo = Handle->AddressInfo->ai_next;
// Return address
// Check valid address
if (Handle->AddressInfo) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Use next resolved Address [%s:%s]->[%s:%u]",
Name, Handle->Name, Handle->HostName, Handle->PortName,
@@ -712,6 +724,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
close( Handle->FD );
Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true;
return -1;
};
@@ -725,6 +738,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
close( Handle->FD );
Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true;
return -1;
};
@@ -938,6 +952,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
// Close socket
close( Handle->FD );
ChangeState( Handle, csFailed );
Handle->AddressFailed = true;
// Start re-open timer
SetStartTime( &(Handle->ReopenStart) );
@@ -978,6 +993,11 @@ int CSelectableCore::Open( THandle * Handle )
default:
FD = -1;
}
// Clear timer
if ((Handle->State == csOpen) || (Handle->State == csWaitingtoOpen)) {
ClearStartTime( &Handle->ReopenStart );
}
return FD;
};
//---------------------------------------------------------------------------
@@ -1149,8 +1169,25 @@ bool CSelectableCore::Write( THandle * Handle )
int BytesWritten = 0;
// Validate
if (!Handle || (Handle->State == csNone) || (Handle->State == csFailed) || (Handle->State == csClosed)) {
return false;
if (!Handle || (Handle->State == csNone) || (Handle->State == csFailed) || (Handle->State == csClosed))
{
if (Handle->AutoManage)
{
// Check duration since last PortIn
if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))
{
// Complete opening process
if (Open( Handle ) == -1) {
// Reset Timer
SetStartTime( &(Handle->ReopenStart) );
}
}
}
else
{
// Must be opened manually
return false;
}
}
// Log Ready for Write Event
@@ -1348,10 +1385,27 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel input disabled", Name, ChannelName );
return 0;
}
else if (Handle->State != csOpen) {
// Handle is not open
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not Open", Name, ChannelName );
return 0;
else if ((Handle->State != csOpen))
{
// Check if auto-managed handle
if (!Handle->AutoManage)
{
// Handle is not open or auto-managed
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not Open (not auto-managed)", Name, ChannelName );
return 0;
}
else
{
// Try to Open handle
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input held, Trying to open (auto-managed) Handle", Name, ChannelName );
Open( Handle );
// Check if Handle is open
if (Handle->State != csOpen) {
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Handle not Open", Name, ChannelName );
return 0;
}
}
}
// Log event
@@ -1434,7 +1488,7 @@ bool CSelectableCore::Process()
while (Handle)
{
// Auto manage handles
if (Handle->AutoManage && ((Handle->State == csNone) || (Handle->State == csFailed) || (Handle->State == csClosed)))
if (Handle->AutoManage && Handle->Persistent && ((Handle->State == csNone) || (Handle->State == csFailed) || (Handle->State == csClosed)))
{
// Check duration since last PortIn
if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))