Important Updates:

- DataTreeCore:
  - Allow types float, int & bool to be read as strings with GetStr()
- LogCore:
  - Add comments to Logging parameters
- WatchDogCore:
  - Call CSelectableCore::Process() in Process() to manage connect
- SelectableCore:
  - Allow SetSocketHandle() to be called if Handle already set as socket
  - added strlcase() method to convert string to lower case
  - Update Handle structure:
    - renamed Address -> HostName
    - renamed PortNo -> PortName
    - added AddressList for all resolved addresses
    - added AddressInfo for active address
  - Add ResolveAddress() method
    - Domain name and protocol port resolving with GetAddrInfo()
  - JSON updated:
    - domain name can be provided instead of IP address
    - protocol can be specified instead of Port No, e.g. "HTTP" / "SSH"
  - Resolve address before connect, or use next resolved address
This commit is contained in:
Charl Wentzel
2017-07-22 09:40:17 +02:00
parent c32875509d
commit aaf3c59727
6 changed files with 174 additions and 84 deletions

View File

@@ -521,7 +521,8 @@ const char * CDataTree::GetStr( TDataMember * BaseMember, const char * Path, con
TDataMember * Member;
// Validate
if ((Member = GetMember( BaseMember, Path, Create )) && (Member->Type == jtString)) {
if ((Member = GetMember( BaseMember, Path, Create )) &&
((Member->Type == jtString) || (Member->Type == jtFloat) || (Member->Type == jtInt) || (Member->Type == jtBool)) ) {
return Member->Value;
}
else if (Member && Create && (Member->Type == jtNull)) {
@@ -539,7 +540,8 @@ const char * CDataTree::GetStr( TDataMember * BaseMember, const char * Path, int
TDataMember * Member;
// Validate
if ((Member = GetMember( BaseMember, Path, Create )) && (Member->Type == jtString)) {
if ((Member = GetMember( BaseMember, Path, Create )) &&
((Member->Type == jtString) || (Member->Type == jtFloat) || (Member->Type == jtInt) || (Member->Type == jtBool)) ) {
Len = Member->Len;
return Member->Value;
}

View File

@@ -61,7 +61,7 @@ bool CLogCore::Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short
va_list ArgPtr;
// Validate values
if (!Buffer || !(Show & (OUT_COUNT |OUT_NORMAL | OUT_HEX | OUT_BIN)))
if (!Buffer || !(Show & (OUT_COUNT | OUT_NORMAL | OUT_HEX | OUT_BIN)))
return false;
// Check debug level

View File

@@ -18,12 +18,12 @@
// Debug options
const short
OUT_COUNT = 1,
OUT_NORMAL = 2,
OUT_HEX = 4,
OUT_BIN = 8,
OUT_CRLF = 16,
OUT_ASIS = 32;
OUT_COUNT = 1, // Show Length of String
OUT_NORMAL = 2, // Show ASCII output (replace non-printable characters (incl. CR/LF with ".")
OUT_HEX = 4, // Show HEX output
OUT_BIN = 8, // Show BINARY output
OUT_CRLF = 16, // with OUT_NORMAL - do not replace CR/LF with "."
OUT_ASIS = 32; // with OUT_NORMAL - do not replace any non-printable character with "."
//---------------------------------------------------------------------------

View File

@@ -26,6 +26,7 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
//---------------------------------------------------------------------------
@@ -73,7 +74,7 @@ bool CSelectableCore::LoadConfigData()
char * Name;
char Path[100];
char * Address;
long Port;
char * Port;
// Call Previous load config
CFunctionCore::LoadConfigData();
@@ -103,26 +104,26 @@ bool CSelectableCore::LoadConfigData()
else if (!strcasecmp( Type, "TCPserver" ))
{
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
Port = DataTree->GetInt( TempMember, "Socket/Port", 0 ); // Get default Port value
Port = (char*)DataTree->GetStr( TempMember, "Socket/Port", "0" ); // Get default Port value
if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
sprintf( Path, "Address/%s/Port", Name );
Port = DataTree->GetInt( NULL, Path, Port, true ); // Get AddressList Port value
Port = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value
}
SetSocketHandle( Handle, ctServer, Address, Port, true ); // Assign values
SetSocketHandle( Handle, ctServer, Address, strlcase(Port), true ); // Assign values
}
else if (!strcasecmp( Type, "TCPclient" ))
{
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
Port = DataTree->GetInt( TempMember, "Socket/Port", 0 ); // Get default Port value
Port = (char*)DataTree->GetStr( TempMember, "Socket/Port", "0" ); // Get default Port value
if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
sprintf( Path, "Address/%s/Port", Name );
Port = DataTree->GetInt( NULL, Path, Port, true ); // Get AddressList Port value
Port = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value
}
SetSocketHandle( Handle, ctClient, Address, Port, true ); // Assign values
SetSocketHandle( Handle, ctClient, Address, strlcase(Port), true ); // Assign values
}
else if (!strcasecmp( Type, "ForkPipe" )) {
Address = (char*)DataTree->GetStr( TempMember, "Fork/ExecPath", NULL, true ); // Get default value
@@ -224,8 +225,12 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
free( Handle->Name );
if (Handle->Path)
free( Handle->Path );
if (Handle->Address)
free( Handle->Address );
if (Handle->HostName)
free( Handle->HostName );
if (Handle->PortName)
free( Handle->PortName );
if (Handle->AddressInfo)
freeaddrinfo( Handle->AddressList );
// Destroy Buffers
if (Handle->InBuffer)
@@ -246,7 +251,7 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
{
// Validate
if (!Handle || (Handle->Type != ctNone) || !FileName) {
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctPort)) || !FileName) {
return false;
}
@@ -293,10 +298,11 @@ bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * Address, const int PortNo, bool KeepAlive )
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive )
{
// Validate
if (!Handle || (Handle->Type != ctNone) || !Address || (Type == ctNone) || (Type == ctPort)) {
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctServer) && (Handle->Type != ctClient) && (Handle->Type != ctRemoteClient)) ||
!((Type == ctServer) || (Type == ctClient) || (Type == ctRemoteClient)) || !HostName || !PortName ) {
return false;
}
@@ -304,18 +310,24 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
Handle->Type = Type;
Handle->KeepAlive = KeepAlive;
// Clear Address
if (Handle->Address) {
free( Handle->Address );
}
// Clear HostName & Port Name
if (Handle->HostName)
free( Handle->HostName );
if (Handle->PortName)
free( Handle->PortName );
if (Handle->AddressList)
freeaddrinfo( Handle->AddressList );
// Set Address & Port
Handle->Address = (char*)malloc( strlen(Address)+1 );
strcpy( Handle->Address, Address );
Handle->PortNo = PortNo;
// Set HostName & Port
Handle->HostName = (char*)malloc( strlen(HostName)+1 );
strcpy( Handle->HostName, HostName );
Handle->PortName = (char*)malloc( strlen(PortName)+1 );
strcpy( Handle->PortName, PortName );
Handle->AddressList = NULL;
Handle->AddressInfo = NULL;
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Set as %s [%s:%d]", Name, Handle->Name, ConnectTypeName[Type], Address, PortNo );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Set as %s [%s:%s]", Name, Handle->Name, ConnectTypeName[Type], HostName, PortName );
return true;
}
//---------------------------------------------------------------------------
@@ -332,11 +344,19 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
free( Handle->Path );
Handle->Path = NULL;
}
if (Handle->Address) {
free( Handle->Address );
Handle->Address = 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;
}
Handle->PortNo = 0;
// Reset Parameters
Handle->Type = ctNone;
@@ -552,11 +572,60 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
//---------------------------------------------------------------------------
bool CSelectableCore::ResolveAddress( THandle * Handle )
{
struct addrinfo hints;
int result;
// Check if more addresses
if (Handle->AddressInfo && Handle->AddressInfo->ai_next)
{
// Set next address
Handle->AddressInfo = Handle->AddressInfo->ai_next;
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Use next resolved Address [%s:%s]->[%s:%u]",
Name, Handle->Name, Handle->HostName, Handle->PortName,
inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr),
ntohs(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_port) );
return true;
}
// Clear existing address list
if (Handle->AddressList) {
freeaddrinfo( Handle->AddressList );
Handle->AddressList = NULL;
Handle->AddressInfo = NULL;
}
// Set address specification
memset( &hints, 0, sizeof hints );
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Resolving Host name [%s:%s]...",
Name, Handle->Name, Handle->HostName, Handle->PortName );
// Resolve Host & Port Names
if ((result = getaddrinfo( Handle->HostName, Handle->PortName, &hints, &(Handle->AddressList))) != 0)
{
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to resolve Host Name [%s:%s] (%s)",
Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(result) );
return false;
}
// Select first address
Handle->AddressInfo = Handle->AddressList;
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Host name resolved [%s:%s]->[%s:%u]",
Name, Handle->Name, Handle->HostName, Handle->PortName,
inet_ntoa(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_addr),
ntohs(((struct sockaddr_in *)Handle->AddressInfo->ai_addr)->sin_port) );
return true;
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenServerSocket( THandle * Handle )
{
socklen_t addr_len;
struct sockaddr_in address;
// Socket options
struct linger ServerLinger_opt;
ServerLinger_opt.l_onoff = 1;
@@ -573,17 +642,19 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
return false;
}
// Create address
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(Handle->Address);
address.sin_port = htons(Handle->PortNo);
addr_len = sizeof(address);
// Resolve Host & Port Names
if (!ResolveAddress( Handle ))
{
// Set Status
ChangeState( Handle, csFailed );
return -1;
}
// Create socket
if ((Handle->FD = socket(AF_INET, SOCK_STREAM, 0)) < 0)
if ((Handle->FD = socket( Handle->AddressInfo->ai_family, Handle->AddressInfo->ai_socktype, Handle->AddressInfo->ai_protocol )) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to create TCP Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to create TCP Server socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
@@ -595,7 +666,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
(setsockopt( Handle->FD, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1))
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not set socket options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not set socket options [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
@@ -610,7 +681,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
@@ -622,10 +693,10 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
fcntl( Handle->FD, F_SETFL, flags | O_NONBLOCK );
// Bind socket
if (bind( Handle->FD, (struct sockaddr *)&address, addr_len ) < 0)
if (bind( Handle->FD, Handle->AddressInfo->ai_addr, Handle->AddressInfo->ai_addrlen ) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to bind TCP Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to bind TCP Server socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
close( Handle->FD );
@@ -638,7 +709,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
if (listen( Handle->FD, 5 ) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to listen on TCP Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to listen on TCP Server socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
close( Handle->FD );
@@ -648,7 +719,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
};
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server binded and listening [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server binded and listening [%s:%s]", Name, Handle->Name, Handle->HostName, Handle->PortName );
// Add to Select Lists
if (Selector) {
@@ -742,7 +813,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
else if (Handle->State == csWaitingtoOpen)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connection open [%s]", Name, Handle->Name, Handle->Address );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connection open [%s]", Name, Handle->Name, Handle->HostName );
// Update state
ChangeState( Handle, csOpen );
@@ -755,9 +826,6 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
int CSelectableCore::OpenClientSocket( THandle * Handle )
{
socklen_t addr_len;
struct sockaddr_in address;
// Socket options
int KeepAlive_opt = 1;
int TCPidle_opt = 5;
@@ -772,11 +840,19 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
if (Handle->State != csWaitingtoOpen)
{
// Resolve IP Address
if (!ResolveAddress( Handle ))
{
// Set Status
ChangeState( Handle, csFailed );
return -1;
}
// Create File descriptor
if ((Handle->FD = socket( AF_INET, SOCK_STREAM, 0 )) < 0)
if ((Handle->FD = socket( Handle->AddressInfo->ai_family, Handle->AddressInfo->ai_socktype, Handle->AddressInfo->ai_protocol )) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to create TCP Client socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to create TCP Client socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set Status
ChangeState( Handle, csFailed );
@@ -795,7 +871,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set State
close( Handle->FD );
@@ -805,15 +881,10 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
}
}
// Declare address
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr( Handle->Address );
address.sin_port = htons( Handle->PortNo );
addr_len = sizeof(address);
if (!connect( Handle->FD, (struct sockaddr *)&address, addr_len ))
// Try to connect to address
if (!connect( Handle->FD, Handle->AddressInfo->ai_addr, Handle->AddressInfo->ai_addrlen ))
{
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client connected [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client connected [%s:%s]", Name, Handle->Name, Handle->HostName, Handle->PortName );
// Add to Select Lists
if (Selector) {
@@ -827,7 +898,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY))
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client waiting to connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client waiting to connect [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Add to Select Lists
if (Selector) {
@@ -841,7 +912,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
else
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client could not connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client could not connect [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Remove from Select List
if (Selector) {
@@ -907,19 +978,21 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
return false;
// Close Children
if (CloseChildren && (Handle->Type == ctServer)) {
if (CloseChildren && (Handle->Type == ctServer))
{
ChildHandle = FirstHandle;
while (ChildHandle) {
if (ChildHandle->Parent == Handle) {
while (ChildHandle)
{
if (ChildHandle->Parent == Handle)
{
// Close and remove handle
NextHandle = ChildHandle->Next;
// Close
Close( ChildHandle );
// Next Handle
ChildHandle = NextHandle;
} else {
// Next Handle
}
else
{
// Skip Handle
ChildHandle = ChildHandle->Next;
}
}
@@ -946,15 +1019,15 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
break;
case ctServer:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server %s [%s:%d]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address, Handle->PortNo );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server %s [%s:%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName, Handle->PortName );
break;
case ctRemoteClient:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName );
break;
case ctClient:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client connection %s [%s:%d]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address, Handle->PortNo );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Client connection %s [%s:%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName, Handle->PortName );
break;
case ctNone:
@@ -969,7 +1042,7 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
}
// Reset FD
Handle->FD = ((Fail)? Handle->FD : -1);
Handle->FD = ((Fail)? Handle->FD : -1);
return true;
}
//---------------------------------------------------------------------------
@@ -1593,3 +1666,4 @@ bool CSelectableCore::BuildArgs( const char * ExecPath, int &Count, char * Args[
return true;
}
//---------------------------------------------------------------------------

View File

@@ -87,9 +87,11 @@ struct SHandle {
pid_t ChildPID; // Forked child PID
char * Address; // Socket IP address
int PortNo; // Socket port no
bool KeepAlive; // Socket keep alive
char * HostName; // Host name or IP adddress
char * PortName; // Socket port no or protocol, e.g. "80" or "HTTP"
struct addrinfo * AddressList; // List of resolved IP Addresses for host name
struct addrinfo * AddressInfo; // Current selected IP Address
bool KeepAlive; // Socket keep alive
// Buffers
CRollingBuffer * InBuffer;
@@ -194,6 +196,7 @@ protected:
virtual int OpenForkPipe( THandle * Handle );
// Socket Operations
bool ResolveAddress( THandle * Handle );
virtual int OpenServerSocket( THandle * Handle );
virtual int OpenRemoteClientSocket( THandle * Handle );
virtual int OpenClientSocket( THandle * Handle );
@@ -208,6 +211,13 @@ protected:
// Specific operations
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] );
// Convert string to lower case
inline char * strlcase( char * Str ) {
for (char * Ch = Str; *Ch; Ch++ )
*Ch = tolower(*Ch);
return Str;
}
public:
// Life Cycle
CSelectableCore( const char * Name, const char * pType = "Selectable" );
@@ -240,7 +250,7 @@ public:
// File Interface
bool SetPortHandle( THandle * Handle, const char * FileName );
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * Address, const int PortNo, bool KeepAlive );
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive );
bool ClearHandle( THandle * Handle );
// FD Operations

View File

@@ -80,6 +80,10 @@ bool CWatchdogCore::Init()
bool CWatchdogCore::Process()
{
// Manage socket connections
CSelectableCore::Process();
// Watchdog ping
if (Timeout( PingTimer, PingInterval ))
{
// Send command