Major Update:

- FunctionCore
  - Replace Channel->Ready with Channel->State (off/waiting/ready)
  - Add Function reference to Handle
- SelectableBare/Core:
  - Implement async address resolve with event handling
    - Create ResolveHandler() signal handler (friend) function
  - Change Create/Remove/DestroyHandle() methods to virtual methods
    - Move socket specific code to SelectableCore
  - Rename ChangeState() to virtual HandleState()
  - Move ClearHandle() from SelectableBare -> SelectableCore
  - Implement new/delete from THandle
  - Set max TCP SYN count on connect
This commit is contained in:
Charl Wentzel
2019-06-09 22:05:27 +02:00
parent 08fce64629
commit bde14a13da
8 changed files with 360 additions and 166 deletions

View File

@@ -68,19 +68,19 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
// Add Channels // Add Channels
if (!(CmdChannel = GetChannel( "Command" ))) if (!(CmdChannel = GetChannel( "Command" )))
CmdChannel = AddChannel( "Command", true ); CmdChannel = AddChannel( "Command", CH_ready );
else else
SetChannelState( CmdChannel, true ); SetChannelState( CmdChannel, CH_ready );
if (!(DeviceChannel = GetChannel( "Device" ))) if (!(DeviceChannel = GetChannel( "Device" )))
DeviceChannel = AddChannel( "Device", true ); DeviceChannel = AddChannel( "Device", CH_ready );
else else
SetChannelState( DeviceChannel, true ); SetChannelState( DeviceChannel, CH_ready );
if (!(EventChannel = GetChannel( "Event" ))) if (!(EventChannel = GetChannel( "Event" )))
EventChannel = AddChannel( "Event", true ); EventChannel = AddChannel( "Event", CH_ready );
else else
SetChannelState( EventChannel, true ); SetChannelState( EventChannel, CH_ready );
// Load Polling configuration // Load Polling configuration
PollConfig = Config->GetChild( "Polling", true ); PollConfig = Config->GetChild( "Polling", true );

View File

@@ -86,7 +86,7 @@ TFileHandle * CFileCore::AddFile( const char * Name, const char * Path, bool Ap
// Create Channel if necessary // Create Channel if necessary
if (CreateChannel) { if (CreateChannel) {
AddChannel( Name, false ); AddChannel( Name, CH_ready );
} }
// Set Parameters // Set Parameters

View File

@@ -100,7 +100,7 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig )
// Load Channels // Load Channels
ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true ); ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true );
while (ChannelConfig) { while (ChannelConfig) {
AddChannel( ChannelConfig->GetName(), false ); AddChannel( ChannelConfig->GetName(), CH_off );
ChannelConfig = ChannelConfig->GetNextPeer(); ChannelConfig = ChannelConfig->GetNextPeer();
} }
@@ -166,7 +166,7 @@ bool CFunctionCore::SetLogLevel( EDebugLevel pDebugLevel )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TChannel * CFunctionCore::AddChannel( const char * ChannelName, bool Ready ) TChannel * CFunctionCore::AddChannel( const char * ChannelName, const EChannelState State )
{ {
TChannel ** Channel = NULL; TChannel ** Channel = NULL;
@@ -190,17 +190,17 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, bool Ready )
(*Channel)->Name = strdup( ChannelName ); (*Channel)->Name = strdup( ChannelName );
(*Channel)->Ref = (char*)malloc( strlen(Name)+strlen(ChannelName)+2 ); (*Channel)->Ref = (char*)malloc( strlen(Name)+strlen(ChannelName)+2 );
sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName ); sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName );
(*Channel)->Ready = Ready; (*Channel)->State = State;
// Log Event // Log Event
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created, Ref:'%s', Ready:%s", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created, Ref:'%s', State:%s",
ProcessName, Name, ChannelName, (*Channel)->Ref, (((*Channel)->Ready)? "Yes" : "No") ); ProcessName, Name, ChannelName, (*Channel)->Ref, ChannelStateName[(*Channel)->State] );
} }
return *Channel; return *Channel;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CFunctionCore::SetChannelState( TChannel * Channel, const bool Ready ) bool CFunctionCore::SetChannelState( TChannel * Channel, const EChannelState State )
{ {
TChannelLink * LinkChannel; TChannelLink * LinkChannel;
@@ -209,14 +209,14 @@ bool CFunctionCore::SetChannelState( TChannel * Channel, const bool Ready )
return false; return false;
// Update state // Update state
Channel->Ready = Ready; Channel->State = State;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Channel '%s' - Ready:%s", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Channel '%s' - State:%s",
ProcessName, Name, Channel->Name, ((Ready)? "Yes" : "No") ); ProcessName, Name, Channel->Name, ChannelStateName[State] );
// Update linked channels // Update linked channels
LinkChannel = Channel->FirstLink; LinkChannel = Channel->FirstLink;
while (LinkChannel) { while (LinkChannel) {
LinkChannel->Function->ChannelStateEvent( LinkChannel->Channel, Channel->Ref, Ready ); LinkChannel->Function->ChannelStateEvent( LinkChannel->Channel, Channel->Ref, State );
LinkChannel = LinkChannel->Next; LinkChannel = LinkChannel->Next;
} }
@@ -224,7 +224,7 @@ bool CFunctionCore::SetChannelState( TChannel * Channel, const bool Ready )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CFunctionCore::ChannelStateEvent( TChannel * Channel, const char * SourceRef, const bool Ready ) bool CFunctionCore::ChannelStateEvent( TChannel * Channel, const char * SourceRef, const EChannelState State )
{ {
TChannelLink * LinkChannel; TChannelLink * LinkChannel;
@@ -233,8 +233,8 @@ bool CFunctionCore::ChannelStateEvent( TChannel * Channel, const char * SourceRe
if (!(LinkChannel = GetLinkChannel( Channel, SourceRef ))) if (!(LinkChannel = GetLinkChannel( Channel, SourceRef )))
return false; return false;
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Link Channel '%s'-->'%s' - Ready:%s", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Link Channel '%s'-->'%s' - State:%s",
ProcessName, Name, Channel->Name, LinkChannel->Channel->Ref, ((Ready)? "Yes" : "No") ); ProcessName, Name, Channel->Name, LinkChannel->Channel->Ref, ChannelStateName[State] );
return true; return true;
} }
@@ -308,9 +308,9 @@ int CFunctionCore::Input( const char * ChannelName, const char * SourceRef, cons
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0; return 0;
} }
else if (!Channel->Ready) { else if (!Channel->State) {
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready", if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel %s",
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName, ChannelStateName[Channel->State] );
return 0; return 0;
} }

View File

@@ -17,6 +17,12 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Enumarate Types
typedef enum { CH_off = 0, CH_wait = 1, CH_ready = 2 } EChannelState;
const char ChannelStateName[][15] = { "Off", "Waiting", "Ready" };
//---------------------------------------------------------------------------
// Preview // Preview
typedef struct SChannel TChannel; typedef struct SChannel TChannel;
typedef struct SChannelLink TChannelLink; typedef struct SChannelLink TChannelLink;
@@ -32,7 +38,7 @@ struct SChannel
TChannelLink * FirstLink = NULL; // List of channels linked for input/output TChannelLink * FirstLink = NULL; // List of channels linked for input/output
bool Ready = false; // Channel ready to receive input EChannelState State = CH_off; // Channel ready to receive input
TChannel * Next = NULL; TChannel * Next = NULL;
}; };
@@ -112,10 +118,10 @@ public:
inline const char * GetType() { return Type; }; inline const char * GetType() { return Type; };
// Manage Channels // Manage Channels
virtual TChannel * AddChannel( const char * ChannelName, const bool Ready ); virtual TChannel * AddChannel( const char * ChannelName, const EChannelState State );
virtual bool SetChannelState( TChannel * Channel, const bool Ready ); virtual bool SetChannelState( TChannel * Channel, const EChannelState State );
virtual bool ChannelStateEvent( TChannel * Channel, const char * SourceRef, const bool Ready ); virtual bool ChannelStateEvent( TChannel * Channel, const char * SourceRef, const EChannelState State );
// Pushing Data Output -> Input // Pushing Data Output -> Input
virtual int Output( const char * ChannelName, const char * TargetRef, const bool SourceRef, const char * Data, int Len = -1 ); virtual int Output( const char * ChannelName, const char * TargetRef, const bool SourceRef, const char * Data, int Len = -1 );

View File

@@ -94,7 +94,7 @@ THandle * CSelectableBare::CreateHandle( const char * HandleName, bool CreateCh
if (!*Handle) if (!*Handle)
{ {
// Create File handle at end of list // Create File handle at end of list
*Handle = (THandle*)calloc( 1, sizeof(THandle) ); *Handle = new THandle;
// Set name // Set name
if (HandleName) { if (HandleName) {
@@ -103,6 +103,7 @@ THandle * CSelectableBare::CreateHandle( const char * HandleName, bool CreateCh
} }
// Set File Descriptor // Set File Descriptor
(*Handle)->Function = this;
(*Handle)->FD = -1; (*Handle)->FD = -1;
// Log event // Log event
@@ -112,7 +113,7 @@ THandle * CSelectableBare::CreateHandle( const char * HandleName, bool CreateCh
// Create Matching Channel // Create Matching Channel
if (CreateChannel) { if (CreateChannel) {
(*Handle)->Channel = AddChannel( HandleName, false ); (*Handle)->Channel = AddChannel( HandleName, CH_off );
} }
return *Handle; return *Handle;
@@ -159,68 +160,16 @@ bool CSelectableBare::DestroyHandle( THandle * Handle )
free( Handle->Name ); free( Handle->Name );
if (Handle->Path) if (Handle->Path)
free( Handle->Path ); free( Handle->Path );
if (Handle->HostName)
free( Handle->HostName );
if (Handle->PortName)
free( Handle->PortName );
if (Handle->AddressInfo)
freeaddrinfo( Handle->AddressList );
// Destroy Buffers
if (Handle->InBuffer)
delete Handle->InBuffer;
if (Handle->OutBuffer)
delete Handle->OutBuffer;
// Clear Input Markers
if (Handle->InMarker)
free( Handle->InMarker );
// Destroy Pointer // Destroy Pointer
free( Handle ); delete Handle;
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableBare::ClearHandle( THandle * Handle ) bool CSelectableBare::HandleState( THandle * Handle, EConnectState State )
{ {
// Validate EChannelState ChannelState = CH_off;
if (!Handle) {
return false;
}
// Reset Type related parameters
if (Handle->Path) {
free( Handle->Path );
Handle->Path = NULL;
}
if (Handle->HostName) {
free( Handle->HostName );
Handle->HostName = NULL;
}
if (Handle->PortName) {
free( Handle->PortName );
Handle->PortName = NULL;
}
if (Handle->AddressList) {
freeaddrinfo( Handle->AddressList );
Handle->AddressList = NULL;
Handle->AddressInfo = NULL;
}
// Reset Parameters
Handle->Type = ctNone;
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Set as None",
ProcessName, Name, Handle->Name );
return true;
}
//---------------------------------------------------------------------------
bool CSelectableBare::ChangeState( THandle * Handle, EConnectState State )
{
bool Ready;
// Validate // Validate
if (!Handle || (Handle->State == State)) if (!Handle || (Handle->State == State))
@@ -235,9 +184,14 @@ bool CSelectableBare::ChangeState( THandle * Handle, EConnectState State )
// Update Channel // Update Channel
if (Handle->Channel) { if (Handle->Channel) {
Ready = ((Handle->State == csOpen) || (Handle->State == csDataWaiting)); if ((Handle->State == csOpenRequest) || (Handle->State == csWaitingtoOpen))
if (Handle->Channel->Ready != Ready) ChannelState = CH_wait;
SetChannelState( Handle->Channel, Ready ); else if ((Handle->State == csOpen) || (Handle->State == csDataWaiting))
ChannelState = CH_ready;
else
ChannelState = CH_off;
if (Handle->Channel->State != ChannelState)
SetChannelState( Handle->Channel, ChannelState );
} }
return true; return true;
} }
@@ -421,7 +375,7 @@ int CSelectableBare::Open( THandle * Handle, bool DelayResolve )
SetStartTime( &Handle->LastAction ); SetStartTime( &Handle->LastAction );
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return (NewHandle)? NewHandle->FD : -1; return (NewHandle)? NewHandle->FD : -1;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -459,7 +413,7 @@ bool CSelectableBare::Close( THandle * Handle, bool QuickReopen )
ProcessName, Name, Handle->Name, ((Fail)? "failed" : "closed") ); ProcessName, Name, Handle->Name, ((Fail)? "failed" : "closed") );
// Set State // Set State
ChangeState( Handle, ((Fail)? csFailed : csClosed) ); HandleState( Handle, ((Fail)? csFailed : csClosed) );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -723,7 +677,7 @@ int CSelectableBare::Input( const char * ChannelName, const char * SourceRef, co
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0; return 0;
} }
else if (!Channel->Ready) { else if (Channel->State != CH_ready) {
// Channel disabled // Channel disabled
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready", if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready",
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );

View File

@@ -40,13 +40,62 @@ CFunctionCore * NewSelectableCore( const char * Name ) {
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Resolve action handlder
void ResolveHandler( int Signal, siginfo_t * SignalInfo, void * Context )
{
TResolveReq * ResolveReq;
THandle * Handle;
// Validate signal
if ((SignalInfo->si_code != SI_ASYNCNL) ||
(SignalInfo->si_signo != SIGRTMIN))
return;
// Get Handle & Request
ResolveReq = (TResolveReq*)(SignalInfo->si_value.sival_ptr);
Handle = ResolveReq->Handle;
((CSelectableCore*)Handle->Function)->HandleResolve( Handle );
}
//---------------------------------------------------------------------------
CSelectableCore::CSelectableCore( const char * pName, const char * pType ) : CSelectableBare( pName, pType ) CSelectableCore::CSelectableCore( const char * pName, const char * pType ) : CSelectableBare( pName, pType )
{ {
// Configure resolve signal handler
ResolveAct.sa_sigaction = &ResolveHandler;
sigemptyset( &ResolveAct.sa_mask );
ResolveAct.sa_flags = SA_SIGINFO;
sigaction( SIGRTMIN, &ResolveAct, NULL );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CSelectableCore::~CSelectableCore() CSelectableCore::~CSelectableCore()
{ {
THandle * NextHandle = NULL;
bool Result;
// Destroy File Handles
while (FirstHandle)
{
// Close active resolve request
if (FirstHandle->Resolving && 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) );
DestroyResolveReq( FirstHandle, true );
HandleState( FirstHandle, csFailed );
}
}
// Close handle if open
if ((FirstHandle->State == csOpen) || (FirstHandle->State == csWaitingtoOpen))
Close( FirstHandle, false );
NextHandle = FirstHandle->Next;
DestroyHandle( FirstHandle );
FirstHandle = NextHandle;
}
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -227,6 +276,87 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableCore::DestroyHandle( THandle * Handle )
{
int Result;
// Validate Handle
if (!Handle)
return false;
// Destroy Resolve request
if (Handle->Resolving && 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) );
}
DestroyResolveReq( Handle, true );
}
// Clear parameters
if (Handle->Name)
free( Handle->Name );
if (Handle->Path)
free( Handle->Path );
if (Handle->HostName)
free( Handle->HostName );
if (Handle->PortName)
free( Handle->PortName );
if (Handle->AddressList)
freeaddrinfo( Handle->AddressList );
// Destroy Buffers
if (Handle->InBuffer)
delete Handle->InBuffer;
if (Handle->OutBuffer)
delete Handle->OutBuffer;
// Clear Input Markers
if (Handle->InMarker)
free( Handle->InMarker );
// Destroy Pointer
delete Handle;
return true;
}
//---------------------------------------------------------------------------
bool CSelectableCore::ClearHandle( THandle * Handle )
{
// Validate
if (!Handle) {
return false;
}
// Reset Type related parameters
if (Handle->Path) {
free( Handle->Path );
Handle->Path = NULL;
}
if (Handle->HostName) {
free( Handle->HostName );
Handle->HostName = NULL;
}
if (Handle->PortName) {
free( Handle->PortName );
Handle->PortName = NULL;
}
if (Handle->AddressList) {
freeaddrinfo( Handle->AddressList );
Handle->AddressList = NULL;
Handle->AddressInfo = NULL;
}
// Reset Parameters
Handle->Type = ctNone;
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Set as None",
ProcessName, Name, Handle->Name );
return true;
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetSerialHandle( THandle * Handle, const char * FileName ) bool CSelectableCore::SetSerialHandle( THandle * Handle, const char * FileName )
{ {
// Validate // Validate
@@ -427,7 +557,7 @@ THandle * CSelectableCore::OpenSerialPort( THandle * Handle )
} }
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -470,7 +600,7 @@ THandle * CSelectableCore::OpenLinePrinterPort( THandle * Handle )
} }
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -572,7 +702,7 @@ THandle * CSelectableCore::OpenForkPipe( THandle * Handle )
} }
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -596,7 +726,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
ProcessName, Name, Handle->Name, Handle->Path, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
} }
@@ -608,7 +738,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
ProcessName, Name, Handle->Name, Handle->Path, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -633,7 +763,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -648,7 +778,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -662,7 +792,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
} }
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -688,7 +818,7 @@ THandle * CSelectableCore::OpenUNIXclientSocket( THandle * Handle )
ProcessName, Name, Handle->Name, Handle->Path, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -715,7 +845,7 @@ THandle * CSelectableCore::OpenUNIXclientSocket( THandle * Handle )
} }
// Set status // Set status
ChangeState( Handle, csWaitingtoOpen ); HandleState( Handle, csWaitingtoOpen );
return Handle; return Handle;
} }
else else
@@ -734,7 +864,7 @@ THandle * CSelectableCore::OpenUNIXclientSocket( THandle * Handle )
Handle->FD = -1; Handle->FD = -1;
Handle->AddressFailed = true; Handle->AddressFailed = true;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
} }
} }
@@ -749,7 +879,7 @@ THandle * CSelectableCore::OpenUNIXclientSocket( THandle * Handle )
} }
// Set status // Set status
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
} }
@@ -846,7 +976,7 @@ THandle * CSelectableCore::OpenUNIXremoteSocket( THandle * Handle )
ProcessName, Name, Handle->Name, Handle->Path ); ProcessName, Name, Handle->Name, Handle->Path );
// Update state // Update state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
} }
@@ -856,12 +986,17 @@ THandle * CSelectableCore::OpenUNIXremoteSocket( THandle * Handle )
bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve ) bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
{ {
struct addrinfo hints; struct addrinfo * Hints;
int result; TResolveReq * ResolveReq;
sigevent ResolveEvt;
int Result;
// Ignore if busy resolving
if (Handle->Resolving)
return false;
// Check if resolved address available // Check if resolved address available
if (Handle->AddressInfo) if (Handle->AddressInfo) {
{
// Return if address still valid // Return if address still valid
if (!Handle->AddressFailed) if (!Handle->AddressFailed)
return true; return true;
@@ -892,47 +1027,117 @@ bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
} }
// Set address specification // Set address specification
memset( &hints, 0, sizeof hints ); Hints = (struct addrinfo*)calloc( 1, sizeof(struct addrinfo) );
if ((Handle->Type == ctTCPserver) || (Handle->Type == ctTCPclient)) { if ((Handle->Type == ctTCPserver) || (Handle->Type == ctTCPclient)) {
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 Hints->ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM; Hints->ai_socktype = SOCK_STREAM;
} else { } else {
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 Hints->ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_DGRAM; Hints->ai_socktype = SOCK_DGRAM;
} }
// Create request data
ResolveReq = new TResolveReq;
Handle->ResolveReq = ResolveReq;
ResolveReq->Handle = Handle;
ResolveReq->Request = (gaicb*)calloc( 1, sizeof(gaicb) );
// DNS request / reply structure
ResolveReq->Request->ar_name = Handle->HostName;
ResolveReq->Request->ar_service = Handle->PortName;
ResolveReq->Request->ar_request = Hints;
ResolveReq->Request->ar_result = NULL;
// Configure signal event
ResolveEvt.sigev_notify = SIGEV_SIGNAL;
ResolveEvt.sigev_signo = SIGRTMIN;
ResolveEvt.sigev_value.sival_ptr = ResolveReq;
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Resolving Host name [%s:%s]...", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Resolving Host name [%s:%s]...",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName );
// Should address be resolved later during process() // Should address be resolved later during process()
if (DelayResolve) if (DelayResolve) {
{
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Delay resolving of Host Name [%s:%s]", 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 ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName );
ChangeState( Handle, csOpenRequest );
HandleState( Handle, csOpenRequest );
return false; return false;
} }
// Resolve Host & Port Names // Resolve Host & Port Names
if ((result = getaddrinfo( Handle->HostName, Handle->PortName, &hints, &(Handle->AddressList))) != 0) Handle->Resolving = true;
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) );
DestroyResolveReq( Handle, true );
HandleState( Handle, csFailed );
return false;
}
return false;
}
//---------------------------------------------------------------------------
bool CSelectableCore::DestroyResolveReq( THandle * Handle, bool DestroyResult )
{ {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to resolve Host Name [%s:%s] (%s)", // Validate
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(result) ); if (!Handle || !Handle->ResolveReq)
ChangeState( Handle, csFailed ); 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)
freeaddrinfo( Handle->ResolveReq->Request->ar_result );
}
if (Handle->ResolveReq->Request->ar_request)
free( (void*)Handle->ResolveReq->Request->ar_request );
if (Handle->ResolveReq->Request)
free( Handle->ResolveReq->Request );
if (Handle->ResolveReq)
delete Handle->ResolveReq;
// Reset request
Handle->ResolveReq = NULL;
Handle->Resolving = false;
return true;
}
//---------------------------------------------------------------------------
bool CSelectableCore::HandleResolve( THandle * Handle )
{
bool Result;
// Validate result
if ((Result = gai_error( Handle->ResolveReq->Request )) != 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) );
DestroyResolveReq( Handle, true );
HandleState( Handle, csFailed );
return false; return false;
} }
// Select first address, skip "0.0.0.0" // Read result
Handle->AddressList = Handle->ResolveReq->Request->ar_result;
Handle->AddressInfo = Handle->AddressList; Handle->AddressInfo = Handle->AddressList;
// Select first address, skip "0.0.0.0"
if (!strcmp( inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr), "0.0.0.0" )) if (!strcmp( inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr), "0.0.0.0" ))
Handle->AddressInfo = Handle->AddressInfo->ai_next; Handle->AddressInfo = Handle->AddressInfo->ai_next;
if (!Handle->AddressInfo) { if (!Handle->AddressInfo) {
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to resolve Host Name [%s:%s] (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to resolve Host Name [%s:%s] (No Result)",
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(result) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName );
freeaddrinfo( Handle->AddressList ); freeaddrinfo( Handle->AddressList );
Handle->AddressList = NULL; Handle->AddressList = NULL;
Handle->AddressInfo = NULL; Handle->AddressInfo = NULL;
ChangeState( Handle, csFailed );
HandleState( Handle, csFailed );
return false; return false;
} }
@@ -941,6 +1146,9 @@ bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName,
inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr), inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr),
ntohs(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_port) ); ntohs(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_port) );
// Destroy request
DestroyResolveReq( Handle, false );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -964,7 +1172,7 @@ THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle, bool DelayReso
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -985,7 +1193,7 @@ THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle, bool DelayReso
Handle->AddressFailed = true; Handle->AddressFailed = true;
// Change state // Change state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -999,7 +1207,7 @@ THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle, bool DelayReso
} }
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -1081,7 +1289,7 @@ THandle * CSelectableCore::OpenUDPclientSocket( THandle * Handle, bool DelayReso
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set Status // Set Status
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -1098,7 +1306,7 @@ THandle * CSelectableCore::OpenUDPclientSocket( THandle * Handle, bool DelayReso
} }
// Set status // Set status
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -1133,7 +1341,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -1146,7 +1354,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
} }
@@ -1161,7 +1369,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Set state
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
} }
@@ -1181,7 +1389,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
Handle->FD = -1; Handle->FD = -1;
Handle->AddressFailed = true; Handle->AddressFailed = true;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -1197,7 +1405,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
Handle->FD = -1; Handle->FD = -1;
Handle->AddressFailed = true; Handle->AddressFailed = true;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -1211,7 +1419,7 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso
} }
// Set state // Set state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -1313,7 +1521,7 @@ THandle * CSelectableCore::OpenTCPremoteSocket( THandle * Handle )
ProcessName, Name, Handle->Name, Handle->HostName ); ProcessName, Name, Handle->Name, Handle->HostName );
// Update state // Update state
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
} }
@@ -1324,10 +1532,11 @@ THandle * CSelectableCore::OpenTCPremoteSocket( THandle * Handle )
THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayResolve ) THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayResolve )
{ {
// Socket options // Socket options
int KeepAlive_opt = 1; int KeepAlive_opt = 1; // Enable/disable keep alive
int TCPidle_opt = 5; int TCPidle_opt = 5; // Idle time on socket before sending first keep alive signal
int TCPcnt_opt = 3; int TCPint_opt = 2; // Interval between keep alive signals
int TCPint_opt = 2; int TCPcnt_opt = 3; // No of missed keep alive response before connection fail
int TCPsyn_opt = 3; // Max SYN (connect retries) before open fails
// Check state // Check state
if (Handle->State == csOpen) { if (Handle->State == csOpen) {
@@ -1349,7 +1558,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set Status // Set Status
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -1361,7 +1570,8 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
if ((setsockopt( Handle->FD, SOL_SOCKET, SO_KEEPALIVE, &KeepAlive_opt, sizeof(KeepAlive_opt)) == -1) || if ((setsockopt( Handle->FD, SOL_SOCKET, SO_KEEPALIVE, &KeepAlive_opt, sizeof(KeepAlive_opt)) == -1) ||
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPIDLE, &TCPidle_opt, sizeof(TCPidle_opt)) == -1) || (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPIDLE, &TCPidle_opt, sizeof(TCPidle_opt)) == -1) ||
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) || (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) ||
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ) (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ||
(setsockopt( Handle->FD, SOL_TCP, TCP_SYNCNT, &TCPsyn_opt, sizeof(TCPsyn_opt)) == -1) )
{ {
// Log Event // Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Could not set KeepAlive options [%s:%s] (%s)", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Could not set KeepAlive options [%s:%s] (%s)",
@@ -1371,7 +1581,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
} }
} }
@@ -1388,7 +1598,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
} }
// Set status // Set status
ChangeState( Handle, csOpen ); HandleState( Handle, csOpen );
return Handle; return Handle;
} }
else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY)) else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY))
@@ -1403,7 +1613,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
} }
// Set status // Set status
ChangeState( Handle, csWaitingtoOpen ); HandleState( Handle, csWaitingtoOpen );
return Handle; return Handle;
} }
else else
@@ -1422,7 +1632,7 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
Handle->FD = -1; Handle->FD = -1;
Handle->AddressFailed = true; Handle->AddressFailed = true;
ChangeState( Handle, csFailed ); HandleState( Handle, csFailed );
return NULL; return NULL;
} }
} }
@@ -1614,7 +1824,7 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
}; };
// Change State // Change State
ChangeState( Handle, ((Fail)? csFailed : csClosed) ); HandleState( Handle, ((Fail)? csFailed : csClosed) );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -10,6 +10,8 @@
// Standard C/C++ Libraries // Standard C/C++ Libraries
#include <ctype.h> #include <ctype.h>
#include <signal.h>
#include <netdb.h>
// redA Libraries // redA Libraries
#include "FunctionCore.h" #include "FunctionCore.h"
@@ -44,13 +46,14 @@ const char ConnectStateName[][15] = { "None", "OpenRequest", "WaitingToOpen", "O
// Previews // Previews
typedef struct SSelectHandle TSelectHandle; typedef struct SSelectHandle TSelectHandle;
typedef struct SHandle THandle; typedef struct SHandle THandle;
typedef struct SResolveReq TResolveReq;
class CSelect; class CSelect;
class CSelectableBare; class CSelectableBare;
class CSelectableCore; class CSelectableCore;
// Callback function for handle events // Callback function for handle events
typedef void (*FHandleCallback)( CSelectableBare * Function, THandle * Handle, EConnectState State ); typedef void (*FHandleCallback)( CSelectableBare * Function, THandle * Handle, EConnectState OldState );
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -68,7 +71,6 @@ struct SSelectHandle {
// List // List
TSelectHandle * Next = NULL; TSelectHandle * Next = NULL;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// List or Handles for Selectable Function Object // List or Handles for Selectable Function Object
@@ -76,6 +78,7 @@ struct SHandle {
// Description // Description
char * Name = NULL; char * Name = NULL;
EConnectType Type = ctNone; EConnectType Type = ctNone;
CSelectableBare * Function = NULL;
// State // State
int FD = -1; int FD = -1;
@@ -103,7 +106,10 @@ struct SHandle {
struct addrinfo * AddressInfo = NULL; // Current selected IP Address struct addrinfo * AddressInfo = NULL; // Current selected IP Address
bool AddressFailed = false; // Indicate failure to connect to address bool AddressFailed = false; // Indicate failure to connect to address
short Queue = 2; // Max waiting connections short Queue = 2; // Max waiting connections
long ResolveDelay = 0; // Delay before resolving hostname via DNS long ResolveDelay = 0; // Delay before resolving hostname via DNS
TResolveReq * ResolveReq = NULL; // DNS resolve request
bool Resolving = false; // Busy resolving address
// Serial Port config // Serial Port config
bool SerialConfig = false; bool SerialConfig = false;
@@ -132,6 +138,16 @@ struct SHandle {
THandle * Parent = NULL; THandle * Parent = NULL;
THandle * Next = NULL; THandle * Next = NULL;
}; };
//---------------------------------------------------------------------------
struct SResolveReq {
THandle * Handle = NULL;
gaicb * Request = NULL;
};
//---------------------------------------------------------------------------
// Resolving
void ResolveHandler( int Signal, siginfo_t * SignalInfo, void * Context );
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -192,9 +208,9 @@ protected:
CSelect * Selector = NULL; CSelect * Selector = NULL;
// Managing File Handles // Managing File Handles
bool RemoveHandle( THandle * Handle ); virtual bool RemoveHandle( THandle * Handle );
bool DestroyHandle( THandle * Handle ); virtual bool DestroyHandle( THandle * Handle );
bool ChangeState( THandle * Handle, EConnectState State ); virtual bool HandleState( THandle * Handle, EConnectState State );
// Get Parameters // Get Parameters
inline int GetFD( const char * HandleName ) { inline int GetFD( const char * HandleName ) {
@@ -241,7 +257,7 @@ public:
} }
// General port parameters // General port parameters
THandle * CreateHandle( const char * HandleName, bool CreateChannel ); virtual THandle * CreateHandle( const char * HandleName, bool CreateChannel );
virtual CDataMember * GetHandleAddress( THandle * Handle, const char * HandleRef ); virtual CDataMember * GetHandleAddress( THandle * Handle, const char * HandleRef );
bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback ); bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback );
@@ -249,9 +265,6 @@ public:
bool SetInBuffer( THandle * Handle, int InBufSize, int InTimeout, const char * InMarker, int InMarkerLen ); bool SetInBuffer( THandle * Handle, int InBufSize, int InTimeout, const char * InMarker, int InMarkerLen );
bool SetOutBuffer( THandle * Handle, int OutBufSize ); bool SetOutBuffer( THandle * Handle, int OutBufSize );
// Specific port parameters
bool ClearHandle( THandle * Handle );
// FD Operations // FD Operations
virtual int Open( THandle * Handle, bool DelayResolve = false ) = 0; virtual int Open( THandle * Handle, bool DelayResolve = false ) = 0;
virtual bool Close( THandle * Handle, bool QuickReopen ); virtual bool Close( THandle * Handle, bool QuickReopen );
@@ -291,6 +304,8 @@ public:
class CSelectableCore : public CSelectableBare class CSelectableCore : public CSelectableBare
{ {
protected: protected:
struct sigaction ResolveAct;
// Port Operations // Port Operations
THandle * OpenSerialPort( THandle * Handle ); THandle * OpenSerialPort( THandle * Handle );
bool WriteSerialConfig( THandle * Handle ); bool WriteSerialConfig( THandle * Handle );
@@ -306,6 +321,11 @@ protected:
// Socket Operations // Socket Operations
bool ResolveAddress( THandle * Handle, bool DelayResolve ); bool ResolveAddress( THandle * Handle, bool DelayResolve );
bool HandleResolve( THandle * Handle );
bool DestroyResolveReq( THandle * Handle, bool DestroyResult );
// Managing File Handles
virtual bool DestroyHandle( THandle * Handle );
THandle * OpenUDPserverSocket( THandle * Handle, bool DelayResolve ); THandle * OpenUDPserverSocket( THandle * Handle, bool DelayResolve );
THandle * OpenUDPremoteSocket( THandle * Handle, char * RemoteAddr, char * RemotePort ); THandle * OpenUDPremoteSocket( THandle * Handle, char * RemoteAddr, char * RemotePort );
@@ -330,6 +350,8 @@ public:
virtual bool Init( CDataMember * FunctionConfig ); virtual bool Init( CDataMember * FunctionConfig );
// Specific port parameters // Specific port parameters
bool ClearHandle( THandle * Handle );
bool SetSerialHandle( THandle * Handle, const char * FileName ); bool SetSerialHandle( THandle * Handle, const char * FileName );
bool SetSerialHandleConfig( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait ); bool SetSerialHandleConfig( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait );
bool SetLinePrinterHandle( THandle * Handle, const char * FileName ); bool SetLinePrinterHandle( THandle * Handle, const char * FileName );
@@ -346,6 +368,8 @@ public:
// Function Interface // Function Interface
virtual int OutputHandle( THandle * Handle, const char * Data, int Len ); virtual int OutputHandle( THandle * Handle, const char * Data, int Len );
virtual bool Process(); virtual bool Process();
friend void ResolveHandler( int Signal, siginfo_t * SignalInfo, void * Context );
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -41,21 +41,21 @@ void ConfigureSignalHandlers()
sigemptyset( &TermAct.sa_mask ); sigemptyset( &TermAct.sa_mask );
TermAct.sa_flags = SA_RESTART; TermAct.sa_flags = SA_RESTART;
sigaction( SIGHUP, &TermAct, 0 ); sigaction( SIGHUP, &TermAct, NULL );
sigaction( SIGINT, &TermAct, 0 ); sigaction( SIGINT, &TermAct, NULL );
sigaction( SIGQUIT, &TermAct, 0 ); sigaction( SIGQUIT, &TermAct, NULL );
sigaction( SIGTERM, &TermAct, 0 ); sigaction( SIGTERM, &TermAct, NULL );
sigaction( SIGTSTP, &TermAct, 0 ); sigaction( SIGTSTP, &TermAct, NULL );
// Signals for immediate termination // Signals for immediate termination
AbortAct.sa_handler = SignalAbort; AbortAct.sa_handler = SignalAbort;
sigemptyset( &AbortAct.sa_mask ); sigemptyset( &AbortAct.sa_mask );
AbortAct.sa_flags = 0; AbortAct.sa_flags = 0;
sigaction( SIGABRT, &AbortAct, 0 ); sigaction( SIGABRT, &AbortAct, NULL );
sigaction( SIGFPE, &AbortAct, 0 ); sigaction( SIGFPE, &AbortAct, NULL );
sigaction( SIGILL, &AbortAct, 0 ); sigaction( SIGILL, &AbortAct, NULL );
sigaction( SIGSEGV, &AbortAct, 0 ); sigaction( SIGSEGV, &AbortAct, NULL );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------