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:
Charl Wentzel
2017-12-10 21:39:55 +02:00
parent 75dec370f7
commit 4ec1dc6cd7
2 changed files with 82 additions and 56 deletions

View File

@@ -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)) ||
@@ -393,7 +404,7 @@ 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 );
} }
} }

View File

@@ -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 )); };