Important Update:

- SelectableCore:
  - Bug fix: StateCallBack array to small
  - Implemented and tested UNIX sockets
  - Started implementation of UDP sockets
  - Add "TCP" to TCP socket related methods and types
This commit is contained in:
Charl Wentzel
2018-11-18 18:29:20 +02:00
parent 85a811c19f
commit 1e74b9cd60
2 changed files with 520 additions and 56 deletions

View File

@@ -15,6 +15,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@@ -101,10 +102,10 @@ bool CSelectableCore::LoadConfigData()
{
if ((Name = (char*)TempMember->GetMemStr( "Port/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get address list value
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get address list value
}
else {
Address = (char*)TempMember->GetMemStr( "Port/Address", NULL, true ); // Get default value
Address = (char*)TempMember->GetMemStr( "Port/Address", NULL, true ); // Get default value
}
SetSerialHandle( Handle, Address );
@@ -140,13 +141,50 @@ bool CSelectableCore::LoadConfigData()
{
if ((Name = (char*)TempMember->GetMemStr( "Port/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get address list value
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get address list value
}
else {
Address = (char*)TempMember->GetMemStr( "Port/Address", NULL, true ); // Get default value
Address = (char*)TempMember->GetMemStr( "Port/Address", NULL, true ); // Get default value
}
SetLinePrinterHandle( Handle, Address );
}
else if (!strcasecmp( Type, "UNIXserver" ))
{
if ((Name = (char*)TempMember->GetMemStr( "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get AddressList Address value
}
else {
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
}
SetUnixHandle( Handle, ctUNIXserver, Address );
}
else if (!strcasecmp( Type, "UNIXclient" ))
{
if ((Name = (char*)TempMember->GetMemStr( "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get AddressList Address value
}
else {
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
}
SetUnixHandle( Handle, ctUNIXclient, Address );
}
else if (!strcasecmp( Type, "UDP" ))
{
if ((Name = (char*)TempMember->GetMemStr( "Socket/Name", NULL ))) {
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetMemStr( Path, NULL, true ); // Get AddressList Address value
sprintf( Path, "Address/%s/Port", Name );
Port = (char*)DataTree->GetMemStr( Path, "0", true ); // Get AddressList Port value
}
else {
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = TempMember->GetMemInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctUDPsock, Address, strlcase(Port), Delay );
}
else if (!strcasecmp( Type, "TCPserver" ))
{
if ((Name = (char*)TempMember->GetMemStr( "Socket/Name", NULL ))) {
@@ -156,11 +194,11 @@ bool CSelectableCore::LoadConfigData()
Port = (char*)DataTree->GetMemStr( Path, "0", true ); // Get AddressList Port value
}
else {
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = TempMember->GetMemInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctServer, Address, strlcase(Port), Delay );
SetSocketHandle( Handle, ctTCPserver, Address, strlcase(Port), Delay );
}
else if (!strcasecmp( Type, "TCPclient" ))
{
@@ -171,14 +209,14 @@ bool CSelectableCore::LoadConfigData()
Port = (char*)DataTree->GetMemStr( Path, "0", true ); // Get AddressList Port value
}
else {
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address value
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
}
Delay = TempMember->GetMemInt( "Socket/ResolveDelay", 0, true );
SetSocketHandle( Handle, ctClient, Address, strlcase(Port), Delay );
SetSocketHandle( Handle, ctTCPclient, Address, strlcase(Port), Delay );
}
else if (!strcasecmp( Type, "ForkPipe" )) {
Address = (char*)TempMember->GetMemStr( "Fork/ExecPath", NULL, true ); // Get default value
Address = (char*)TempMember->GetMemStr( "Fork/ExecPath", NULL, true ); // Get default value
SetForkPipeHandle( Handle, Address );
}
@@ -396,11 +434,39 @@ bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetUnixHandle( THandle * Handle, EConnectType Type, const char * FileName )
{
// Validate
if (!Handle || !FileName ||
!((Type == ctUNIXserver) || (Type == ctUNIXclient) || (Type == ctUNIXremote)) ||
!((Handle->Type == ctNone) || (Handle->Type == Type)) ) {
return false;
}
// Set Type
Handle->Type = Type;
// Clear File Name
if (Handle->Path) {
free( Handle->Path );
}
// Set name
Handle->Path = (char*)malloc( strlen(FileName)+1 );
strcpy( Handle->Path, FileName );
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Set as %s [%s]", Name, Handle->Name, ConnectTypeName[Type], FileName );
return true;
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay )
{
// Validate
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctServer) && (Handle->Type != ctClient) && (Handle->Type != ctRemoteClient)) ||
!((Type == ctServer) || (Type == ctClient) || (Type == ctRemoteClient)) || !HostName || !PortName ) {
if (!Handle || !HostName || !PortName ||
!((Type == ctUDPsock) || (Type == ctTCPserver) || (Type == ctTCPclient) || (Type == ctTCPremote)) ||
!((Handle->Type == ctNone) || (Handle->Type == Type)) ) {
return false;
}
@@ -419,8 +485,10 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
// 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;
@@ -651,7 +719,7 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
if (!Handle->Path || !*(Handle->Path))
{
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Invalid path for Exec", Name, Handle->Name );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - No path specified for Exec", Name, Handle->Name );
return -1;
}
@@ -727,7 +795,268 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
ChangeState( Handle, csOpen );
return Handle->FD;
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
{
socklen_t addr_len;
struct sockaddr_un address;
// Validate
if (Handle->Type != ctUNIXserver) {
return false;
} else if (Handle->State == csOpen) {
return Handle->FD;
}
// Remove old socket
if (unlink( Handle->Path ) && (errno != ENOENT)) {
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to remove old UNIX Server socket [%s] (%s)", Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
return -1;
}
// Create socket
if ((Handle->FD = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to create new UNIX Server socket [%s] (%s)", Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
return -1;
};
// Set non-blocking flag
int flags = fcntl( Handle->FD, F_GETFL, 0 );
fcntl( Handle->FD, F_SETFL, flags | O_NONBLOCK );
// Name Socket
memset( &address, 0, sizeof(struct sockaddr_un) );
address.sun_family = AF_UNIX;
strcpy( address.sun_path, Handle->Path );
addr_len = sizeof(address);
// Bind socket
if (bind( Handle->FD, (struct sockaddr*)&address, addr_len ) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to bind UNIX Server socket [%s] (%s)", Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state
close( Handle->FD );
Handle->FD = -1;
ChangeState( Handle, csFailed );
return -1;
};
// Create que for 5 connections
if (listen( Handle->FD, 5 ) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to listen on UNIX Server socket [%s] (%s)", Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state
close( Handle->FD );
Handle->FD = -1;
ChangeState( Handle, csFailed );
return -1;
};
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Server binded and listening [%s]", Name, Handle->Name, Handle->Path );
// Add to Select Lists
if (Selector) {
Selector->Add( Handle->FD, true, false, Handle, this );
}
// Set state
ChangeState( Handle, csOpen );
return Handle->FD;
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenUNIXclientSocket( THandle * Handle )
{
socklen_t addr_len;
struct sockaddr_un address;
// Check state
if (Handle->State == csOpen) {
// Already open
return Handle->FD;
}
if (Handle->State != csWaitingtoOpen)
{
// Create socket
if ((Handle->FD = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to create new UNIX Client socket [%s] (%s)", Name, Handle->Name, Handle->Path, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
return -1;
};
// Set non-blocking flag
int flags = fcntl( Handle->FD, F_GETFL, 0 );
fcntl( Handle->FD, F_SETFL, flags | O_NONBLOCK );
// Name Socket
memset( &address, 0, sizeof(struct sockaddr_un) );
address.sun_family = AF_UNIX;
strcpy( address.sun_path, Handle->Path );
addr_len = sizeof(address);
// Try to connect to address
if (!connect( Handle->FD, (struct sockaddr*)&address, addr_len ))
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Client waiting to connect [%s]", Name, Handle->Name, Handle->Path );
// Add to Select Lists
if (Selector) {
Selector->Add( Handle->FD, true, true, Handle, this );
}
// Set status
ChangeState( Handle, csWaitingtoOpen );
return Handle->FD;
}
else
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Client could not connect [%s] (%s)", Name, Handle->Name, Handle->Path, strerror(errno) );
// Remove from Select List
if (Selector) {
Selector->Remove( Handle->FD, true, true );
}
// Close socket
close( Handle->FD );
ChangeState( Handle, csFailed );
Handle->AddressFailed = true;
// Reset Handle
Handle->FD = -1;
return -1;
}
}
else
{
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Client connected [%s]", Name, Handle->Name, Handle->Path );
// Add to Select Lists
if (Selector) {
Selector->Add( Handle->FD, true, true, Handle, this );
}
// Set status
ChangeState( Handle, csOpen );
return Handle->FD;
}
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenUNIXremoteSocket( THandle * Handle )
{
THandle ** RemoteClient;
int ClientFD;
char ClientName[100];
socklen_t addr_len;
struct sockaddr_un address;
// Validate
if (!Handle) {
return -1;
}
// Check Handle type
if (Handle->Type == ctUNIXserver)
{
// Accept connection on current socket
addr_len = sizeof( address );
if ((ClientFD = accept( Handle->FD, (struct sockaddr *)&address, &addr_len)) == -1)
{
// Log Event
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Server failed to accept blocking connection (%s)", Name, Handle->Name, strerror(errno) );
}
else {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Server failed to accept connection (%s)", Name, Handle->Name, strerror(errno) );
}
return -1;
}
// Set non-blocking flag
int flags = fcntl( ClientFD, F_GETFL, 0 );
fcntl( ClientFD, F_SETFL, flags | O_NONBLOCK );
// Get end of client list
RemoteClient = &FirstHandle;
while (*RemoteClient) {
RemoteClient = &((*RemoteClient)->Next);
}
// Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
*RemoteClient = CreateHandle( ClientName, false );
if (!SetUnixHandle( *RemoteClient, ctUNIXremote, Handle->Path )) {
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Server failed to configure Remote UNIX Client connection (%s)", Name, Handle->Name, strerror(errno) );
return -1;
}
// Copy Parent Buffer setup
SetInBuffer( *RemoteClient, ((Handle->InBuffer)? Handle->InBuffer->Size() : 0),
Handle->InTimeout, Handle->InMarker, Handle->InMarkerLen );
SetOutBuffer( *RemoteClient, ((Handle->OutBuffer)? Handle->OutBuffer->Size() : 0) );
// Set Key parameters
(*RemoteClient)->FD = ClientFD;
(*RemoteClient)->Parent = Handle;
(*RemoteClient)->State = csWaitingtoOpen;
// Reset Timer
SetStartTime( &((*RemoteClient)->LastAction) );
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Server accepted Remote Client connection [%s]", Name, Handle->Name, (*RemoteClient)->Path );
// Add to Select Lists
if (Selector) {
Selector->Add( (*RemoteClient)->FD, true, true, *RemoteClient, this );
}
return (*RemoteClient)->FD;
}
else if (Handle->Type == ctUNIXremote)
{
// Check state
if (Handle->State == csOpen)
{
// Already open
return Handle->FD;
}
else if (Handle->State == csWaitingtoOpen)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote UNIX Client connected [%s]", Name, Handle->Name, Handle->Path );
// Update state
ChangeState( Handle, csOpen );
return Handle->FD;
}
}
return -1;
}
//---------------------------------------------------------------------------
bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
@@ -816,7 +1145,95 @@ bool CSelectableCore::ResolveAddress( THandle * Handle, bool DelayResolve )
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenServerSocket( THandle * Handle, bool DelayResolve )
int CSelectableCore::OpenUDPsocket( THandle * Handle, bool DelayResolve )
{
// Socket options
struct linger ServerLinger_opt;
ServerLinger_opt.l_onoff = 1;
ServerLinger_opt.l_linger = 5;
int Reuse_opt = 1;
int KeepAlive_opt = 1;
// Validate Handle
if (Handle->Type != ctUDPsock) {
return false;
}
// Resolve Host & Port Names
if (!ResolveAddress( Handle, DelayResolve ))
return -1;
// Create socket
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 UDP Server socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
return -1;
};
// Configure connection
if ((setsockopt( Handle->FD, SOL_SOCKET, SO_LINGER, &ServerLinger_opt, sizeof(ServerLinger_opt)) == -1) ||
(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:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
ChangeState( Handle, csFailed );
return -1;
}
// Set non-blocking flag
int flags = fcntl( Handle->FD, F_GETFL, 0 );
fcntl( Handle->FD, F_SETFL, flags | O_NONBLOCK );
// Bind socket
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 UDP Server socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
close( Handle->FD );
Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true;
return -1;
};
// Create que for 5 connections
if (listen( Handle->FD, 5 ) < 0)
{
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Failed to listen on UDP Server socket [%s:%s] (%s)", Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state
close( Handle->FD );
Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true;
return -1;
};
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UDP Server binded and listening [%s:%s]", Name, Handle->Name, Handle->HostName, Handle->PortName );
// Add to Select Lists
if (Selector) {
Selector->Add( Handle->FD, true, false, Handle, this );
}
// Set state
ChangeState( Handle, csOpen );
return Handle->FD;
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayResolve )
{
// Socket options
struct linger ServerLinger_opt;
@@ -830,7 +1247,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle, bool DelayResolve )
int TCPcnt_opt = 3;
// Validate Handle
if (Handle->Type != ctServer) {
if (Handle->Type != ctTCPserver) {
return false;
}
@@ -921,7 +1338,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle, bool DelayResolve )
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
int CSelectableCore::OpenTCPremoteSocket( THandle * Handle )
{
THandle ** RemoteClient;
int ClientFD;
@@ -938,7 +1355,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
}
// Check Handle type
if (Handle->Type == ctServer)
if (Handle->Type == ctTCPserver)
{
// Accept connection on current socket
addr_len = sizeof( address );
@@ -972,7 +1389,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
// Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
*RemoteClient = CreateHandle( ClientName, false );
if (!SetSocketHandle( *RemoteClient, ctRemoteClient, ClientAddress, ClientPort, 0 )) {
if (!SetSocketHandle( *RemoteClient, ctTCPremote, 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) );
return -1;
}
@@ -1000,7 +1417,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
return (*RemoteClient)->FD;
}
else if (Handle->Type == ctRemoteClient)
else if (Handle->Type == ctTCPremote)
{
// Check state
if (Handle->State == csOpen)
@@ -1011,7 +1428,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->HostName );
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connected [%s]", Name, Handle->Name, Handle->HostName );
// Update state
ChangeState( Handle, csOpen );
@@ -1022,7 +1439,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
}
//---------------------------------------------------------------------------
int CSelectableCore::OpenClientSocket( THandle * Handle, bool DelayResolve )
int CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayResolve )
{
// Socket options
int KeepAlive_opt = 1;
@@ -1144,14 +1561,26 @@ int CSelectableCore::Open( THandle * Handle, bool DelayResolve )
case ctForkPipe :
FD = OpenForkPipe( Handle );
break;
case ctServer :
FD = OpenServerSocket( Handle, DelayResolve );
case ctUNIXserver :
FD = OpenUNIXserverSocket( Handle );
break;
case ctClient :
FD = OpenClientSocket( Handle, DelayResolve );
case ctUNIXclient :
FD = OpenUNIXclientSocket( Handle );
break;
case ctRemoteClient :
FD = OpenRemoteClientSocket( Handle );
case ctUNIXremote :
FD = OpenUNIXremoteSocket( Handle );
break;
case ctUDPsock :
FD = OpenUDPsocket( Handle, DelayResolve );
break;
case ctTCPserver :
FD = OpenTCPserverSocket( Handle, DelayResolve );
break;
case ctTCPclient :
FD = OpenTCPclientSocket( Handle, DelayResolve );
break;
case ctTCPremote :
FD = OpenTCPremoteSocket( Handle );
break;
default:
FD = -1;
@@ -1175,7 +1604,7 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
return false;
// Close Children
if (Handle->Type == ctServer)
if ((Handle->Type == ctTCPserver) || (Handle->Type == ctUNIXserver))
{
ChildHandle = FirstHandle;
while (ChildHandle)
@@ -1223,15 +1652,31 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Forked Pipe %s", Name, Handle->Name, ((Fail)? "failed" : "closed"));
break;
case ctServer:
case ctUNIXserver:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Server %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
break;
case ctUNIXclient:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
break;
case ctUNIXremote:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UNIX Remote Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
break;
case ctUDPsock:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - UDP Socket connection %s [%s:%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName, Handle->PortName );
break;
case ctTCPserver:
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->HostName );
case ctTCPremote:
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Remote Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName );
break;
case ctClient:
case ctTCPclient:
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;
@@ -1268,10 +1713,14 @@ bool CSelectableCore::Read( THandle * Handle )
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Read Event", Name, Handle->Name );
// Check for closing/opening event on Socket
if (Handle->Type == ctServer)
if ((Handle->Type == ctTCPserver) || (Handle->Type == ctUNIXserver))
{
// Incoming client request
ClientFD = OpenRemoteClientSocket( Handle );
if (Handle->Type == ctTCPserver) {
ClientFD = OpenTCPremoteSocket( Handle );
} else if (Handle->Type == ctUNIXserver) {
ClientFD = OpenUNIXremoteSocket( Handle );
}
if (ClientFD == -1) {
return false;
}
@@ -1284,15 +1733,20 @@ bool CSelectableCore::Read( THandle * Handle )
}
return true;
}
else if ((Handle->Type == ctRemoteClient) || (Handle->Type == ctClient))
else if ((Handle->Type == ctTCPremote) || (Handle->Type == ctTCPclient) ||
(Handle->Type == ctUNIXremote) || (Handle->Type == ctUNIXclient) )
{
// Check if socket ready (non-block open in progress)
if (Handle->State == csWaitingtoOpen)
{
if (Handle->Type == ctRemoteClient) {
OpenRemoteClientSocket( Handle );
} else if (Handle->Type == ctClient) {
OpenClientSocket( Handle, true );
if (Handle->Type == ctTCPremote) {
OpenTCPremoteSocket( Handle );
} else if (Handle->Type == ctTCPclient) {
OpenTCPclientSocket( Handle, true );
} else if (Handle->Type == ctUNIXremote) {
OpenUNIXremoteSocket( Handle );
} else if (Handle->Type == ctUNIXclient) {
OpenUNIXclientSocket( Handle );
}
// Reset Timer (for auto-close)
SetStartTime( &(Handle->LastAction) );
@@ -1314,7 +1768,7 @@ bool CSelectableCore::Read( THandle * Handle )
Close( Handle, false );
// Destroy Client
if (Handle->Type == ctRemoteClient) {
if ((Handle->Type == ctTCPremote) || (Handle->Type == ctTCPremote)) {
RemoveHandle( Handle );
}
return false;
@@ -1402,10 +1856,14 @@ bool CSelectableCore::Write( THandle * Handle )
if (Handle->State == csWaitingtoOpen)
{
// Complete socket open process
if (Handle->Type == ctRemoteClient) {
OpenRemoteClientSocket( Handle );
} else if (Handle->Type == ctClient) {
OpenClientSocket( Handle, true );
if (Handle->Type == ctTCPremote) {
OpenTCPremoteSocket( Handle );
} else if (Handle->Type == ctTCPclient) {
OpenTCPclientSocket( Handle, true );
} else if (Handle->Type == ctUNIXremote) {
OpenUNIXremoteSocket( Handle );
} else if (Handle->Type == ctUNIXclient) {
OpenUNIXclientSocket( Handle );
}
// Reset Timer (for auto-close)
SetStartTime( &(Handle->LastAction) );
@@ -1477,7 +1935,7 @@ bool CSelectableCore::ProcessInputBuffer( THandle * Handle, bool Force )
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - IN-T:", Name, Handle->Name );
// Write buffer to Outputs
if (Handle->Type == ctRemoteClient) {
if ((Handle->Type == ctTCPremote) || (Handle->Type == ctUNIXremote)) {
Output( Handle->Parent->Channel, Data, Len );
} else {
Output( Handle->Channel, Data, Len );
@@ -1496,7 +1954,7 @@ bool CSelectableCore::ProcessInputBuffer( THandle * Handle, bool Force )
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - IN-M:", Name, Handle->Name );
// Write buffer to Outputs
if (Handle->Type == ctRemoteClient) {
if ((Handle->Type == ctTCPremote) || (Handle->Type == ctUNIXremote)) {
Output( Handle->Parent->Channel, Data, Len );
} else {
Output( Handle->Channel, Data, Len );
@@ -1666,7 +2124,7 @@ int CSelectableCore::OutputHandle( THandle * Handle, const char * Data, int Len
Len = strlen( Data );
}
if (Handle->Type == ctServer)
if ((Handle->Type == ctTCPserver) || (Handle->Type == ctUNIXserver))
{
// Cannot write to server socket, so Update Remote Client connections individually
ChildHandle = FirstHandle;
@@ -1775,7 +2233,7 @@ bool CSelectableCore::Process()
}
// Check for auto close (but not on servers)
if ((Handle->State == csOpen) && (Handle->Type != ctServer) && Handle->AutoManage && !Handle->Persistent)
if ((Handle->State == csOpen) && (Handle->Type != ctTCPserver) && (Handle->Type != ctUNIXserver) && Handle->AutoManage && !Handle->Persistent)
{
// Close port after timeout
if (Timeout( Handle->LastAction, Handle->CloseTimeout )) {