Important Update:
- Add Resolve Delay, allow time delay before resolving address Allow completion of other actions before blocking all to getaddr() - Remove Handle->KeepAlive, assume always true
This commit is contained in:
@@ -77,6 +77,7 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
char * FlowCtrlText;
|
char * FlowCtrlText;
|
||||||
short Parity;
|
short Parity;
|
||||||
short FlowCtrl;
|
short FlowCtrl;
|
||||||
|
long Delay;
|
||||||
|
|
||||||
// Call Previous load config
|
// Call Previous load config
|
||||||
CFunctionCore::LoadConfigData();
|
CFunctionCore::LoadConfigData();
|
||||||
@@ -96,11 +97,13 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
||||||
if (!strcasecmp( Type, "Serial" ))
|
if (!strcasecmp( Type, "Serial" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL ); // Get default value
|
|
||||||
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
sprintf( Path, "Address/%s/Address", Name );
|
||||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL, true ); // Get default value
|
||||||
|
}
|
||||||
SetSerialHandle( Handle, Address );
|
SetSerialHandle( Handle, Address );
|
||||||
|
|
||||||
// Update configuration if specified
|
// Update configuration if specified
|
||||||
@@ -133,36 +136,44 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
}
|
}
|
||||||
else if (!strcasecmp( Type, "LinePrinter" ))
|
else if (!strcasecmp( Type, "LinePrinter" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL ); // Get default value
|
|
||||||
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
sprintf( Path, "Address/%s/Address", Name );
|
||||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL, true ); // Get default value
|
||||||
|
}
|
||||||
SetLinePrinterHandle( Handle, Address );
|
SetLinePrinterHandle( Handle, Address );
|
||||||
}
|
}
|
||||||
else if (!strcasecmp( Type, "TCPserver" ))
|
else if (!strcasecmp( Type, "TCPserver" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address 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 = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value
|
Port = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value
|
||||||
}
|
}
|
||||||
SetSocketHandle( Handle, ctServer, Address, strlcase(Port), true ); // Assign values
|
else {
|
||||||
|
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL, true ); // Get default Address value
|
||||||
|
Port = (char*)DataTree->GetStr( TempMember, "Socket/Port", "0", true ); // Get default Port value
|
||||||
|
}
|
||||||
|
Delay = DataTree->GetInt( TempMember, "Socket/ResolveDelay", 0, true );
|
||||||
|
SetSocketHandle( Handle, ctServer, Address, strlcase(Port), Delay );
|
||||||
}
|
}
|
||||||
else if (!strcasecmp( Type, "TCPclient" ))
|
else if (!strcasecmp( Type, "TCPclient" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address 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 = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value
|
Port = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value
|
||||||
}
|
}
|
||||||
SetSocketHandle( Handle, ctClient, Address, strlcase(Port), true ); // Assign values
|
else {
|
||||||
|
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL, true ); // Get default Address value
|
||||||
|
Port = (char*)DataTree->GetStr( TempMember, "Socket/Port", "0", true ); // Get default Port value
|
||||||
|
}
|
||||||
|
Delay = DataTree->GetInt( TempMember, "Socket/ResolveDelay", 0, true );
|
||||||
|
SetSocketHandle( Handle, ctClient, Address, strlcase(Port), Delay );
|
||||||
}
|
}
|
||||||
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
|
||||||
@@ -383,7 +394,7 @@ bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive )
|
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay )
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctServer) && (Handle->Type != ctClient) && (Handle->Type != ctRemoteClient)) ||
|
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctServer) && (Handle->Type != ctClient) && (Handle->Type != ctRemoteClient)) ||
|
||||||
@@ -392,8 +403,8 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set Type
|
// Set Type
|
||||||
Handle->Type = Type;
|
Handle->Type = Type;
|
||||||
Handle->KeepAlive = KeepAlive;
|
Handle->ResolveDelay = ResolveDelay;
|
||||||
|
|
||||||
// Clear HostName & Port Name
|
// Clear HostName & Port Name
|
||||||
if (Handle->HostName)
|
if (Handle->HostName)
|
||||||
@@ -717,7 +728,7 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::ResolveAddress( THandle * Handle )
|
bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
|
||||||
{
|
{
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int result;
|
int result;
|
||||||
@@ -762,11 +773,21 @@ bool CSelectableCore::ResolveAddress( THandle * Handle )
|
|||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Resolving Host name [%s:%s]...",
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Resolving Host name [%s:%s]...",
|
||||||
Name, Handle->Name, Handle->HostName, Handle->PortName );
|
Name, Handle->Name, Handle->HostName, Handle->PortName );
|
||||||
|
|
||||||
|
// Should address be resolved later during process()
|
||||||
|
if (DelayResolve)
|
||||||
|
{
|
||||||
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Delay resolving of Host Name [%s:%s]",
|
||||||
|
Name, Handle->Name, Handle->HostName, Handle->PortName );
|
||||||
|
ChangeState( Handle, csOpenRequest );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve Host & Port Names
|
// Resolve Host & Port Names
|
||||||
if ((result = getaddrinfo( Handle->HostName, Handle->PortName, &hints, &(Handle->AddressList))) != 0)
|
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)",
|
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) );
|
Name, Handle->Name, Handle->HostName, Handle->PortName, gai_strerror(result) );
|
||||||
|
ChangeState( Handle, csFailed );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,6 +801,7 @@ bool CSelectableCore::ResolveAddress( THandle * Handle )
|
|||||||
freeaddrinfo( Handle->AddressList );
|
freeaddrinfo( Handle->AddressList );
|
||||||
Handle->AddressList = NULL;
|
Handle->AddressList = NULL;
|
||||||
Handle->AddressInfo = NULL;
|
Handle->AddressInfo = NULL;
|
||||||
|
ChangeState( Handle, csFailed );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,7 +814,7 @@ bool CSelectableCore::ResolveAddress( THandle * Handle )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CSelectableCore::OpenServerSocket( THandle * Handle )
|
int CSelectableCore::OpenServerSocket( THandle * Handle, bool DelayResolve )
|
||||||
{
|
{
|
||||||
// Socket options
|
// Socket options
|
||||||
struct linger ServerLinger_opt;
|
struct linger ServerLinger_opt;
|
||||||
@@ -811,12 +833,8 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resolve Host & Port Names
|
// Resolve Host & Port Names
|
||||||
if (!ResolveAddress( Handle ))
|
if (!ResolveAddress( Handle, DelayResolve ))
|
||||||
{
|
|
||||||
// Set Status
|
|
||||||
ChangeState( Handle, csFailed );
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
// Create socket
|
// Create socket
|
||||||
if ((Handle->FD = socket( Handle->AddressInfo->ai_family, Handle->AddressInfo->ai_socktype, Handle->AddressInfo->ai_protocol )) < 0)
|
if ((Handle->FD = socket( Handle->AddressInfo->ai_family, Handle->AddressInfo->ai_socktype, Handle->AddressInfo->ai_protocol )) < 0)
|
||||||
@@ -842,11 +860,10 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure TCP keep alive settings
|
// Configure TCP keep alive settings
|
||||||
if (Handle->KeepAlive &&
|
if ((setsockopt( Handle->FD, SOL_SOCKET, SO_KEEPALIVE, &KeepAlive_opt, sizeof(KeepAlive_opt)) == -1) ||
|
||||||
((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) ))
|
|
||||||
{
|
{
|
||||||
// Log Event
|
// Log Event
|
||||||
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) );
|
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) );
|
||||||
@@ -953,7 +970,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
|||||||
// Create Remote Client Handle
|
// Create Remote Client Handle
|
||||||
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
|
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
|
||||||
*RemoteClient = CreateHandle( ClientName, false );
|
*RemoteClient = CreateHandle( ClientName, false );
|
||||||
if (!SetSocketHandle( *RemoteClient, ctRemoteClient, ClientAddress, ClientPort, Handle->KeepAlive )) {
|
if (!SetSocketHandle( *RemoteClient, ctRemoteClient, ClientAddress, ClientPort, 0 )) {
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server failed to configure Remote TCP Client connection (%s)", Name, Handle->Name, strerror(errno) );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server failed to configure Remote TCP Client connection (%s)", Name, Handle->Name, strerror(errno) );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1003,7 +1020,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CSelectableCore::OpenClientSocket( THandle * Handle )
|
int CSelectableCore::OpenClientSocket( THandle * Handle, bool DelayResolve )
|
||||||
{
|
{
|
||||||
// Socket options
|
// Socket options
|
||||||
int KeepAlive_opt = 1;
|
int KeepAlive_opt = 1;
|
||||||
@@ -1020,12 +1037,8 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
|||||||
if (Handle->State != csWaitingtoOpen)
|
if (Handle->State != csWaitingtoOpen)
|
||||||
{
|
{
|
||||||
// Resolve IP Address
|
// Resolve IP Address
|
||||||
if (!ResolveAddress( Handle ))
|
if (!ResolveAddress( Handle, DelayResolve ))
|
||||||
{
|
|
||||||
// Set Status
|
|
||||||
ChangeState( Handle, csFailed );
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
// Create File descriptor
|
// Create File descriptor
|
||||||
if ((Handle->FD = socket( Handle->AddressInfo->ai_family, Handle->AddressInfo->ai_socktype, Handle->AddressInfo->ai_protocol )) < 0)
|
if ((Handle->FD = socket( Handle->AddressInfo->ai_family, Handle->AddressInfo->ai_socktype, Handle->AddressInfo->ai_protocol )) < 0)
|
||||||
@@ -1043,11 +1056,10 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
|||||||
fcntl( Handle->FD, F_SETFL, O_NONBLOCK|flags );
|
fcntl( Handle->FD, F_SETFL, O_NONBLOCK|flags );
|
||||||
|
|
||||||
// Configure TCP keep alive settings
|
// Configure TCP keep alive settings
|
||||||
if (Handle->KeepAlive &&
|
if ((setsockopt( Handle->FD, SOL_SOCKET, SO_KEEPALIVE, &KeepAlive_opt, sizeof(KeepAlive_opt)) == -1) ||
|
||||||
((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) ))
|
|
||||||
{
|
{
|
||||||
// Log Event
|
// Log Event
|
||||||
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) );
|
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) );
|
||||||
@@ -1110,7 +1122,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CSelectableCore::Open( THandle * Handle )
|
int CSelectableCore::Open( THandle * Handle, bool DelayResolve )
|
||||||
{
|
{
|
||||||
int FD = -1;
|
int FD = -1;
|
||||||
|
|
||||||
@@ -1131,10 +1143,10 @@ int CSelectableCore::Open( THandle * Handle )
|
|||||||
FD = OpenForkPipe( Handle );
|
FD = OpenForkPipe( Handle );
|
||||||
break;
|
break;
|
||||||
case ctServer :
|
case ctServer :
|
||||||
FD = OpenServerSocket( Handle );
|
FD = OpenServerSocket( Handle, DelayResolve );
|
||||||
break;
|
break;
|
||||||
case ctClient :
|
case ctClient :
|
||||||
FD = OpenClientSocket( Handle );
|
FD = OpenClientSocket( Handle, DelayResolve );
|
||||||
break;
|
break;
|
||||||
case ctRemoteClient :
|
case ctRemoteClient :
|
||||||
FD = OpenRemoteClientSocket( Handle );
|
FD = OpenRemoteClientSocket( Handle );
|
||||||
@@ -1278,7 +1290,7 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
if (Handle->Type == ctRemoteClient) {
|
if (Handle->Type == ctRemoteClient) {
|
||||||
OpenRemoteClientSocket( Handle );
|
OpenRemoteClientSocket( Handle );
|
||||||
} else if (Handle->Type == ctClient) {
|
} else if (Handle->Type == ctClient) {
|
||||||
OpenClientSocket( Handle );
|
OpenClientSocket( Handle, true );
|
||||||
}
|
}
|
||||||
// Reset Timer (for auto-close)
|
// Reset Timer (for auto-close)
|
||||||
SetStartTime( &(Handle->LastAction) );
|
SetStartTime( &(Handle->LastAction) );
|
||||||
@@ -1378,7 +1390,7 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
|
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
|
||||||
{
|
{
|
||||||
// Attempt to re-open port
|
// Attempt to re-open port
|
||||||
Open( Handle );
|
Open( Handle, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1391,7 +1403,7 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
if (Handle->Type == ctRemoteClient) {
|
if (Handle->Type == ctRemoteClient) {
|
||||||
OpenRemoteClientSocket( Handle );
|
OpenRemoteClientSocket( Handle );
|
||||||
} else if (Handle->Type == ctClient) {
|
} else if (Handle->Type == ctClient) {
|
||||||
OpenClientSocket( Handle );
|
OpenClientSocket( Handle, true );
|
||||||
}
|
}
|
||||||
// Reset Timer (for auto-close)
|
// Reset Timer (for auto-close)
|
||||||
SetStartTime( &(Handle->LastAction) );
|
SetStartTime( &(Handle->LastAction) );
|
||||||
@@ -1623,10 +1635,14 @@ int CSelectableCore::OutputHandle( THandle * Handle, const char * Data, int Len
|
|||||||
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
|
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
|
||||||
{
|
{
|
||||||
// Complete opening process
|
// Complete opening process
|
||||||
Open( Handle );
|
Open( Handle, true );
|
||||||
|
|
||||||
// Check if Handle is open
|
// Check if Handle is open
|
||||||
if (Handle->State == csWaitingtoOpen) {
|
if (Handle->State == csOpenRequest) {
|
||||||
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Request to resolve (auto-managed) Handle", Name, Handle->Name );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (Handle->State == csWaitingtoOpen) {
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Waiting to open (auto-managed) Handle", Name, Handle->Name );
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Waiting to open (auto-managed) Handle", Name, Handle->Name );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1727,11 +1743,18 @@ bool CSelectableCore::Process()
|
|||||||
while (Handle)
|
while (Handle)
|
||||||
{
|
{
|
||||||
// Auto manage handles
|
// Auto manage handles
|
||||||
if ((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent)
|
if ((Handle->State == csOpenRequest))
|
||||||
|
{
|
||||||
|
// Resolve then open socket
|
||||||
|
if (Timeout( Handle->LastAction, Handle->ResolveDelay )) {
|
||||||
|
Open( Handle, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent) )
|
||||||
{
|
{
|
||||||
// Try to re-open port after delay
|
// Try to re-open port after delay
|
||||||
if (Timeout( Handle->LastAction, Handle->ReopenDelay )) {
|
if (Timeout( Handle->LastAction, Handle->ReopenDelay )) {
|
||||||
Open( Handle );
|
Open( Handle, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
typedef enum { ctNone = 0, ctSerial = 1, ctLinePrinter = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5, ctForkPipe = 6 } EConnectType;
|
typedef enum { ctNone = 0, ctSerial = 1, ctLinePrinter = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5, ctForkPipe = 6 } EConnectType;
|
||||||
const char ConnectTypeName[][15] = { "None", "Port", "ForkPipe", "Server", "RemoteClient", "Client" };
|
const char ConnectTypeName[][15] = { "None", "Port", "ForkPipe", "Server", "RemoteClient", "Client" };
|
||||||
|
|
||||||
typedef enum { csNone = 0, csWaitingtoOpen = 1, csOpen = 2, csDataWaiting = 3, csClosed = 4, csFailed = 5 } EConnectState;
|
typedef enum { csNone = 0, csOpenRequest = 1, csWaitingtoOpen = 2, csOpen = 3, csDataWaiting = 4, csClosed = 5, csFailed = 6 } EConnectState;
|
||||||
const char ConnectStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
const char ConnectStateName[][15] = { "None", "OpenRequest", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -79,8 +79,8 @@ struct SHandle {
|
|||||||
bool AutoManage;
|
bool AutoManage;
|
||||||
bool Persistent;
|
bool Persistent;
|
||||||
timeval LastAction;
|
timeval LastAction;
|
||||||
long ReopenDelay; // millisecs
|
long ReopenDelay; // millisecs before trying to re-open socket
|
||||||
long CloseTimeout; // millisecs
|
long CloseTimeout; // millisecs of no traffic before closing socket
|
||||||
|
|
||||||
// Callback functions
|
// Callback functions
|
||||||
FHandleCallback StateCallback[ 6 ];
|
FHandleCallback StateCallback[ 6 ];
|
||||||
@@ -88,15 +88,18 @@ struct SHandle {
|
|||||||
// Type specific parameters
|
// Type specific parameters
|
||||||
char * Path; // Port (file)name or Exec path
|
char * Path; // Port (file)name or Exec path
|
||||||
|
|
||||||
|
// Fork config
|
||||||
pid_t ChildPID; // Forked child PID
|
pid_t ChildPID; // Forked child PID
|
||||||
|
|
||||||
|
// Socket config
|
||||||
char * HostName; // Host name or IP adddress
|
char * HostName; // Host name or IP adddress
|
||||||
char * PortName; // Socket port no or protocol, e.g. "80" or "HTTP"
|
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 * AddressList; // List of resolved IP Addresses for host name
|
||||||
struct addrinfo * AddressInfo; // Current selected IP Address
|
struct addrinfo * AddressInfo; // Current selected IP Address
|
||||||
bool AddressFailed; // Indicate failure to connect to address
|
bool AddressFailed; // Indicate failure to connect to address
|
||||||
bool KeepAlive; // Socket keep alive
|
long ResolveDelay; // Delay before resolving hostname via DNS
|
||||||
|
|
||||||
|
// Serial Port config
|
||||||
bool SerialConfig;
|
bool SerialConfig;
|
||||||
int InBaudrate;
|
int InBaudrate;
|
||||||
int OutBaudrate;
|
int OutBaudrate;
|
||||||
@@ -209,10 +212,10 @@ protected:
|
|||||||
int OpenForkPipe( THandle * Handle );
|
int OpenForkPipe( THandle * Handle );
|
||||||
|
|
||||||
// Socket Operations
|
// Socket Operations
|
||||||
bool ResolveAddress( THandle * Handle );
|
bool ResolveAddress( THandle * Handle, bool DelayResolve );
|
||||||
int OpenServerSocket( THandle * Handle );
|
int OpenServerSocket( THandle * Handle, bool DelayResolve );
|
||||||
int OpenRemoteClientSocket( THandle * Handle );
|
int OpenRemoteClientSocket( THandle * Handle );
|
||||||
int OpenClientSocket( THandle * Handle );
|
int OpenClientSocket( THandle * Handle, bool DelayResolve );
|
||||||
|
|
||||||
// Mutual Operations
|
// Mutual Operations
|
||||||
int ReadFromFD( int FD, char * Data, int MaxLen );
|
int ReadFromFD( int FD, char * Data, int MaxLen );
|
||||||
@@ -266,17 +269,17 @@ public:
|
|||||||
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 );
|
||||||
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
|
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
|
||||||
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive );
|
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay );
|
||||||
bool ClearHandle( THandle * Handle );
|
bool ClearHandle( THandle * Handle );
|
||||||
|
|
||||||
// FD Operations
|
// FD Operations
|
||||||
virtual int Open( THandle * Handle );
|
virtual int Open( THandle * Handle, bool DelayResolve = false );
|
||||||
virtual bool Close( THandle * Handle, bool QuickReopen );
|
virtual bool Close( THandle * Handle, bool QuickReopen );
|
||||||
virtual bool Read( THandle * Handle );
|
virtual bool Read( THandle * Handle );
|
||||||
virtual bool Write( THandle * Handle );
|
virtual bool Write( THandle * Handle );
|
||||||
|
|
||||||
// FD operations
|
// FD operations
|
||||||
inline virtual int Open( const char * HandleName ) { return (Open( GetHandle( HandleName ))); };
|
inline virtual int Open( const char * HandleName, bool DelayResolve = false ) { return (Open( GetHandle( HandleName ), DelayResolve)); };
|
||||||
|
|
||||||
inline virtual bool Close( const char * HandleName, bool QuickReopen ) { return (Close( GetHandle( HandleName ), QuickReopen )); };
|
inline virtual bool Close( const char * HandleName, bool QuickReopen ) { return (Close( GetHandle( HandleName ), QuickReopen )); };
|
||||||
inline virtual bool Close( int FD, bool QuickReopen ) { return (Close( GetHandle( FD ), QuickReopen )); };
|
inline virtual bool Close( int FD, bool QuickReopen ) { return (Close( GetHandle( FD ), QuickReopen )); };
|
||||||
|
|||||||
Reference in New Issue
Block a user