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; TDataMember * Member;
// Validate // 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; return Member->Value;
} }
else if (Member && Create && (Member->Type == jtNull)) { else if (Member && Create && (Member->Type == jtNull)) {
@@ -539,7 +540,8 @@ const char * CDataTree::GetStr( TDataMember * BaseMember, const char * Path, int
TDataMember * Member; TDataMember * Member;
// Validate // 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; Len = Member->Len;
return Member->Value; return Member->Value;
} }

View File

@@ -18,12 +18,12 @@
// Debug options // Debug options
const short const short
OUT_COUNT = 1, OUT_COUNT = 1, // Show Length of String
OUT_NORMAL = 2, OUT_NORMAL = 2, // Show ASCII output (replace non-printable characters (incl. CR/LF with ".")
OUT_HEX = 4, OUT_HEX = 4, // Show HEX output
OUT_BIN = 8, OUT_BIN = 8, // Show BINARY output
OUT_CRLF = 16, OUT_CRLF = 16, // with OUT_NORMAL - do not replace CR/LF with "."
OUT_ASIS = 32; 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/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -73,7 +74,7 @@ bool CSelectableCore::LoadConfigData()
char * Name; char * Name;
char Path[100]; char Path[100];
char * Address; char * Address;
long Port; char * Port;
// Call Previous load config // Call Previous load config
CFunctionCore::LoadConfigData(); CFunctionCore::LoadConfigData();
@@ -103,26 +104,26 @@ bool CSelectableCore::LoadConfigData()
else if (!strcasecmp( Type, "TCPserver" )) else if (!strcasecmp( Type, "TCPserver" ))
{ {
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value 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 ))) { if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name ); sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
sprintf( Path, "Address/%s/Port", Name ); 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" )) else if (!strcasecmp( Type, "TCPclient" ))
{ {
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value 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 ))) { if ((Name = (char*)DataTree->GetStr( TempMember, "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name ); sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get AddressList Address value
sprintf( Path, "Address/%s/Port", Name ); 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" )) { else if (!strcasecmp( Type, "ForkPipe" )) {
Address = (char*)DataTree->GetStr( TempMember, "Fork/ExecPath", NULL, true ); // Get default value Address = (char*)DataTree->GetStr( TempMember, "Fork/ExecPath", NULL, true ); // Get default value
@@ -224,8 +225,12 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
free( Handle->Name ); free( Handle->Name );
if (Handle->Path) if (Handle->Path)
free( Handle->Path ); free( Handle->Path );
if (Handle->Address) if (Handle->HostName)
free( Handle->Address ); free( Handle->HostName );
if (Handle->PortName)
free( Handle->PortName );
if (Handle->AddressInfo)
freeaddrinfo( Handle->AddressList );
// Destroy Buffers // Destroy Buffers
if (Handle->InBuffer) if (Handle->InBuffer)
@@ -246,7 +251,7 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName ) bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
{ {
// Validate // Validate
if (!Handle || (Handle->Type != ctNone) || !FileName) { if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctPort)) || !FileName) {
return false; 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 // 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; return false;
} }
@@ -304,18 +310,24 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
Handle->Type = Type; Handle->Type = Type;
Handle->KeepAlive = KeepAlive; Handle->KeepAlive = KeepAlive;
// Clear Address // Clear HostName & Port Name
if (Handle->Address) { if (Handle->HostName)
free( Handle->Address ); free( Handle->HostName );
} if (Handle->PortName)
free( Handle->PortName );
if (Handle->AddressList)
freeaddrinfo( Handle->AddressList );
// Set Address & Port // Set HostName & Port
Handle->Address = (char*)malloc( strlen(Address)+1 ); Handle->HostName = (char*)malloc( strlen(HostName)+1 );
strcpy( Handle->Address, Address ); strcpy( Handle->HostName, HostName );
Handle->PortNo = PortNo; Handle->PortName = (char*)malloc( strlen(PortName)+1 );
strcpy( Handle->PortName, PortName );
Handle->AddressList = NULL;
Handle->AddressInfo = NULL;
// Log event // 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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -332,11 +344,19 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
free( Handle->Path ); free( Handle->Path );
Handle->Path = NULL; Handle->Path = NULL;
} }
if (Handle->Address) { if (Handle->HostName) {
free( Handle->Address ); free( Handle->HostName );
Handle->Address = NULL; 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 // Reset Parameters
Handle->Type = ctNone; 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 ) int CSelectableCore::OpenServerSocket( THandle * Handle )
{ {
socklen_t addr_len;
struct sockaddr_in address;
// Socket options // Socket options
struct linger ServerLinger_opt; struct linger ServerLinger_opt;
ServerLinger_opt.l_onoff = 1; ServerLinger_opt.l_onoff = 1;
@@ -573,17 +642,19 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
return false; return false;
} }
// Create address // Resolve Host & Port Names
address.sin_family = AF_INET; if (!ResolveAddress( Handle ))
address.sin_addr.s_addr = inet_addr(Handle->Address); {
address.sin_port = htons(Handle->PortNo); // Set Status
addr_len = sizeof(address); ChangeState( Handle, csFailed );
return -1;
}
// Create socket // 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 // 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 // Set state
ChangeState( Handle, csFailed ); 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)) (setsockopt( Handle->FD, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1))
{ {
// Log Event // 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 // Set state
ChangeState( Handle, csFailed ); 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) )) (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{ {
// Log Event // 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 // Set state
ChangeState( Handle, csFailed ); ChangeState( Handle, csFailed );
@@ -622,10 +693,10 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
fcntl( Handle->FD, F_SETFL, flags | O_NONBLOCK ); fcntl( Handle->FD, F_SETFL, flags | O_NONBLOCK );
// Bind socket // 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 // 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 // Set state
close( Handle->FD ); close( Handle->FD );
@@ -638,7 +709,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
if (listen( Handle->FD, 5 ) < 0) if (listen( Handle->FD, 5 ) < 0)
{ {
// Log Event // 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 // Set state
close( Handle->FD ); close( Handle->FD );
@@ -648,7 +719,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
}; };
// Log Event // 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 // Add to Select Lists
if (Selector) { if (Selector) {
@@ -742,7 +813,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
else if (Handle->State == csWaitingtoOpen) else if (Handle->State == csWaitingtoOpen)
{ {
// Log Event // 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 // Update state
ChangeState( Handle, csOpen ); ChangeState( Handle, csOpen );
@@ -755,9 +826,6 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
int CSelectableCore::OpenClientSocket( THandle * Handle ) int CSelectableCore::OpenClientSocket( THandle * Handle )
{ {
socklen_t addr_len;
struct sockaddr_in address;
// Socket options // Socket options
int KeepAlive_opt = 1; int KeepAlive_opt = 1;
int TCPidle_opt = 5; int TCPidle_opt = 5;
@@ -772,11 +840,19 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
if (Handle->State != csWaitingtoOpen) if (Handle->State != csWaitingtoOpen)
{ {
// Resolve IP Address
if (!ResolveAddress( Handle ))
{
// Set Status
ChangeState( Handle, csFailed );
return -1;
}
// Create File descriptor // 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 // 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 // Set Status
ChangeState( Handle, csFailed ); 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) )) (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{ {
// Log Event // 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 // Set State
close( Handle->FD ); close( Handle->FD );
@@ -805,15 +881,10 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
} }
} }
// Declare address // Try to connect to address
address.sin_family = AF_INET; if (!connect( Handle->FD, Handle->AddressInfo->ai_addr, Handle->AddressInfo->ai_addrlen ))
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 ))
{ {
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 // Add to Select Lists
if (Selector) { if (Selector) {
@@ -827,7 +898,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY)) else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY))
{ {
// Log Event // 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 // Add to Select Lists
if (Selector) { if (Selector) {
@@ -841,7 +912,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
else else
{ {
// Log Event // 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 // Remove from Select List
if (Selector) { if (Selector) {
@@ -907,19 +978,21 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
return false; return false;
// Close Children // Close Children
if (CloseChildren && (Handle->Type == ctServer)) { if (CloseChildren && (Handle->Type == ctServer))
{
ChildHandle = FirstHandle; ChildHandle = FirstHandle;
while (ChildHandle) { while (ChildHandle)
if (ChildHandle->Parent == Handle) { {
if (ChildHandle->Parent == Handle)
{
// Close and remove handle
NextHandle = ChildHandle->Next; NextHandle = ChildHandle->Next;
// Close
Close( ChildHandle ); Close( ChildHandle );
// Next Handle
ChildHandle = NextHandle; ChildHandle = NextHandle;
} else { }
// Next Handle else
{
// Skip Handle
ChildHandle = ChildHandle->Next; ChildHandle = ChildHandle->Next;
} }
} }
@@ -946,15 +1019,15 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
break; break;
case ctServer: 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; break;
case ctRemoteClient: 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; break;
case ctClient: 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; break;
case ctNone: case ctNone:
@@ -1593,3 +1666,4 @@ bool CSelectableCore::BuildArgs( const char * ExecPath, int &Count, char * Args[
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -87,8 +87,10 @@ struct SHandle {
pid_t ChildPID; // Forked child PID pid_t ChildPID; // Forked child PID
char * Address; // Socket IP address char * HostName; // Host name or IP adddress
int PortNo; // Socket port no 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 bool KeepAlive; // Socket keep alive
// Buffers // Buffers
@@ -194,6 +196,7 @@ protected:
virtual int OpenForkPipe( THandle * Handle ); virtual int OpenForkPipe( THandle * Handle );
// Socket Operations // Socket Operations
bool ResolveAddress( THandle * Handle );
virtual int OpenServerSocket( THandle * Handle ); virtual int OpenServerSocket( THandle * Handle );
virtual int OpenRemoteClientSocket( THandle * Handle ); virtual int OpenRemoteClientSocket( THandle * Handle );
virtual int OpenClientSocket( THandle * Handle ); virtual int OpenClientSocket( THandle * Handle );
@@ -208,6 +211,13 @@ protected:
// Specific operations // Specific operations
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] ); 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: public:
// Life Cycle // Life Cycle
CSelectableCore( const char * Name, const char * pType = "Selectable" ); CSelectableCore( const char * Name, const char * pType = "Selectable" );
@@ -240,7 +250,7 @@ public:
// File Interface // File Interface
bool SetPortHandle( THandle * Handle, const char * FileName ); bool SetPortHandle( THandle * Handle, const char * FileName );
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath ); 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 ); bool ClearHandle( THandle * Handle );
// FD Operations // FD Operations

View File

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