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:
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
@@ -101,10 +102,10 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
{
|
{
|
||||||
if ((Name = (char*)TempMember->GetMemStr( "Port/Name", NULL ))) {
|
if ((Name = (char*)TempMember->GetMemStr( "Port/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
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 {
|
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 );
|
SetSerialHandle( Handle, Address );
|
||||||
|
|
||||||
@@ -140,13 +141,50 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
{
|
{
|
||||||
if ((Name = (char*)TempMember->GetMemStr( "Port/Name", NULL ))) {
|
if ((Name = (char*)TempMember->GetMemStr( "Port/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
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 {
|
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 );
|
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" ))
|
else if (!strcasecmp( Type, "TCPserver" ))
|
||||||
{
|
{
|
||||||
if ((Name = (char*)TempMember->GetMemStr( "Socket/Name", NULL ))) {
|
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
|
Port = (char*)DataTree->GetMemStr( Path, "0", true ); // Get AddressList Port value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address 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
|
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
|
||||||
}
|
}
|
||||||
Delay = TempMember->GetMemInt( "Socket/ResolveDelay", 0, true );
|
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" ))
|
else if (!strcasecmp( Type, "TCPclient" ))
|
||||||
{
|
{
|
||||||
@@ -171,14 +209,14 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
Port = (char*)DataTree->GetMemStr( Path, "0", true ); // Get AddressList Port value
|
Port = (char*)DataTree->GetMemStr( Path, "0", true ); // Get AddressList Port value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Address = (char*)TempMember->GetMemStr( "Socket/Address", NULL, true ); // Get default Address 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
|
Port = (char*)TempMember->GetMemStr( "Socket/Port", "0", true ); // Get default Port value
|
||||||
}
|
}
|
||||||
Delay = TempMember->GetMemInt( "Socket/ResolveDelay", 0, true );
|
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" )) {
|
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 );
|
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 )
|
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 || !HostName || !PortName ||
|
||||||
!((Type == ctServer) || (Type == ctClient) || (Type == ctRemoteClient)) || !HostName || !PortName ) {
|
!((Type == ctUDPsock) || (Type == ctTCPserver) || (Type == ctTCPclient) || (Type == ctTCPremote)) ||
|
||||||
|
!((Handle->Type == ctNone) || (Handle->Type == Type)) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,8 +485,10 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
|
|||||||
// Set HostName & Port
|
// Set HostName & Port
|
||||||
Handle->HostName = (char*)malloc( strlen(HostName)+1 );
|
Handle->HostName = (char*)malloc( strlen(HostName)+1 );
|
||||||
strcpy( Handle->HostName, HostName );
|
strcpy( Handle->HostName, HostName );
|
||||||
|
|
||||||
Handle->PortName = (char*)malloc( strlen(PortName)+1 );
|
Handle->PortName = (char*)malloc( strlen(PortName)+1 );
|
||||||
strcpy( Handle->PortName, PortName );
|
strcpy( Handle->PortName, PortName );
|
||||||
|
|
||||||
Handle->AddressList = NULL;
|
Handle->AddressList = NULL;
|
||||||
Handle->AddressInfo = NULL;
|
Handle->AddressInfo = NULL;
|
||||||
|
|
||||||
@@ -651,7 +719,7 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
|
|||||||
if (!Handle->Path || !*(Handle->Path))
|
if (!Handle->Path || !*(Handle->Path))
|
||||||
{
|
{
|
||||||
// Log event
|
// 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,7 +795,268 @@ int CSelectableCore::OpenForkPipe( THandle * Handle )
|
|||||||
ChangeState( Handle, csOpen );
|
ChangeState( Handle, csOpen );
|
||||||
return Handle->FD;
|
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 )
|
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
|
// Socket options
|
||||||
struct linger ServerLinger_opt;
|
struct linger ServerLinger_opt;
|
||||||
@@ -830,7 +1247,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle, bool DelayResolve )
|
|||||||
int TCPcnt_opt = 3;
|
int TCPcnt_opt = 3;
|
||||||
|
|
||||||
// Validate Handle
|
// Validate Handle
|
||||||
if (Handle->Type != ctServer) {
|
if (Handle->Type != ctTCPserver) {
|
||||||
return false;
|
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;
|
THandle ** RemoteClient;
|
||||||
int ClientFD;
|
int ClientFD;
|
||||||
@@ -938,7 +1355,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check Handle type
|
// Check Handle type
|
||||||
if (Handle->Type == ctServer)
|
if (Handle->Type == ctTCPserver)
|
||||||
{
|
{
|
||||||
// Accept connection on current socket
|
// Accept connection on current socket
|
||||||
addr_len = sizeof( address );
|
addr_len = sizeof( address );
|
||||||
@@ -972,7 +1389,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, 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) );
|
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;
|
||||||
}
|
}
|
||||||
@@ -1000,7 +1417,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
|||||||
|
|
||||||
return (*RemoteClient)->FD;
|
return (*RemoteClient)->FD;
|
||||||
}
|
}
|
||||||
else if (Handle->Type == ctRemoteClient)
|
else if (Handle->Type == ctTCPremote)
|
||||||
{
|
{
|
||||||
// Check state
|
// Check state
|
||||||
if (Handle->State == csOpen)
|
if (Handle->State == csOpen)
|
||||||
@@ -1011,7 +1428,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->HostName );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connected [%s]", Name, Handle->Name, Handle->HostName );
|
||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
ChangeState( Handle, csOpen );
|
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
|
// Socket options
|
||||||
int KeepAlive_opt = 1;
|
int KeepAlive_opt = 1;
|
||||||
@@ -1144,14 +1561,26 @@ int CSelectableCore::Open( THandle * Handle, bool DelayResolve )
|
|||||||
case ctForkPipe :
|
case ctForkPipe :
|
||||||
FD = OpenForkPipe( Handle );
|
FD = OpenForkPipe( Handle );
|
||||||
break;
|
break;
|
||||||
case ctServer :
|
case ctUNIXserver :
|
||||||
FD = OpenServerSocket( Handle, DelayResolve );
|
FD = OpenUNIXserverSocket( Handle );
|
||||||
break;
|
break;
|
||||||
case ctClient :
|
case ctUNIXclient :
|
||||||
FD = OpenClientSocket( Handle, DelayResolve );
|
FD = OpenUNIXclientSocket( Handle );
|
||||||
break;
|
break;
|
||||||
case ctRemoteClient :
|
case ctUNIXremote :
|
||||||
FD = OpenRemoteClientSocket( Handle );
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
FD = -1;
|
FD = -1;
|
||||||
@@ -1175,7 +1604,7 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Close Children
|
// Close Children
|
||||||
if (Handle->Type == ctServer)
|
if ((Handle->Type == ctTCPserver) || (Handle->Type == ctUNIXserver))
|
||||||
{
|
{
|
||||||
ChildHandle = FirstHandle;
|
ChildHandle = FirstHandle;
|
||||||
while (ChildHandle)
|
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"));
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Forked Pipe %s", Name, Handle->Name, ((Fail)? "failed" : "closed"));
|
||||||
break;
|
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 );
|
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 ctTCPremote:
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Remote TCP Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Remote Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->HostName );
|
||||||
break;
|
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 );
|
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;
|
||||||
|
|
||||||
@@ -1268,10 +1713,14 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Read Event", Name, Handle->Name );
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Read Event", Name, Handle->Name );
|
||||||
|
|
||||||
// Check for closing/opening event on Socket
|
// Check for closing/opening event on Socket
|
||||||
if (Handle->Type == ctServer)
|
if ((Handle->Type == ctTCPserver) || (Handle->Type == ctUNIXserver))
|
||||||
{
|
{
|
||||||
// Incoming client request
|
// Incoming client request
|
||||||
ClientFD = OpenRemoteClientSocket( Handle );
|
if (Handle->Type == ctTCPserver) {
|
||||||
|
ClientFD = OpenTCPremoteSocket( Handle );
|
||||||
|
} else if (Handle->Type == ctUNIXserver) {
|
||||||
|
ClientFD = OpenUNIXremoteSocket( Handle );
|
||||||
|
}
|
||||||
if (ClientFD == -1) {
|
if (ClientFD == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1284,15 +1733,20 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
}
|
}
|
||||||
return true;
|
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)
|
// Check if socket ready (non-block open in progress)
|
||||||
if (Handle->State == csWaitingtoOpen)
|
if (Handle->State == csWaitingtoOpen)
|
||||||
{
|
{
|
||||||
if (Handle->Type == ctRemoteClient) {
|
if (Handle->Type == ctTCPremote) {
|
||||||
OpenRemoteClientSocket( Handle );
|
OpenTCPremoteSocket( Handle );
|
||||||
} else if (Handle->Type == ctClient) {
|
} else if (Handle->Type == ctTCPclient) {
|
||||||
OpenClientSocket( Handle, true );
|
OpenTCPclientSocket( Handle, true );
|
||||||
|
} else if (Handle->Type == ctUNIXremote) {
|
||||||
|
OpenUNIXremoteSocket( Handle );
|
||||||
|
} else if (Handle->Type == ctUNIXclient) {
|
||||||
|
OpenUNIXclientSocket( Handle );
|
||||||
}
|
}
|
||||||
// Reset Timer (for auto-close)
|
// Reset Timer (for auto-close)
|
||||||
SetStartTime( &(Handle->LastAction) );
|
SetStartTime( &(Handle->LastAction) );
|
||||||
@@ -1314,7 +1768,7 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
Close( Handle, false );
|
Close( Handle, false );
|
||||||
|
|
||||||
// Destroy Client
|
// Destroy Client
|
||||||
if (Handle->Type == ctRemoteClient) {
|
if ((Handle->Type == ctTCPremote) || (Handle->Type == ctTCPremote)) {
|
||||||
RemoveHandle( Handle );
|
RemoveHandle( Handle );
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1402,10 +1856,14 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
if (Handle->State == csWaitingtoOpen)
|
if (Handle->State == csWaitingtoOpen)
|
||||||
{
|
{
|
||||||
// Complete socket open process
|
// Complete socket open process
|
||||||
if (Handle->Type == ctRemoteClient) {
|
if (Handle->Type == ctTCPremote) {
|
||||||
OpenRemoteClientSocket( Handle );
|
OpenTCPremoteSocket( Handle );
|
||||||
} else if (Handle->Type == ctClient) {
|
} else if (Handle->Type == ctTCPclient) {
|
||||||
OpenClientSocket( Handle, true );
|
OpenTCPclientSocket( Handle, true );
|
||||||
|
} else if (Handle->Type == ctUNIXremote) {
|
||||||
|
OpenUNIXremoteSocket( Handle );
|
||||||
|
} else if (Handle->Type == ctUNIXclient) {
|
||||||
|
OpenUNIXclientSocket( Handle );
|
||||||
}
|
}
|
||||||
// Reset Timer (for auto-close)
|
// Reset Timer (for auto-close)
|
||||||
SetStartTime( &(Handle->LastAction) );
|
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 );
|
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - IN-T:", Name, Handle->Name );
|
||||||
|
|
||||||
// Write buffer to Outputs
|
// Write buffer to Outputs
|
||||||
if (Handle->Type == ctRemoteClient) {
|
if ((Handle->Type == ctTCPremote) || (Handle->Type == ctUNIXremote)) {
|
||||||
Output( Handle->Parent->Channel, Data, Len );
|
Output( Handle->Parent->Channel, Data, Len );
|
||||||
} else {
|
} else {
|
||||||
Output( Handle->Channel, Data, Len );
|
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 );
|
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - IN-M:", Name, Handle->Name );
|
||||||
|
|
||||||
// Write buffer to Outputs
|
// Write buffer to Outputs
|
||||||
if (Handle->Type == ctRemoteClient) {
|
if ((Handle->Type == ctTCPremote) || (Handle->Type == ctUNIXremote)) {
|
||||||
Output( Handle->Parent->Channel, Data, Len );
|
Output( Handle->Parent->Channel, Data, Len );
|
||||||
} else {
|
} else {
|
||||||
Output( Handle->Channel, Data, Len );
|
Output( Handle->Channel, Data, Len );
|
||||||
@@ -1666,7 +2124,7 @@ int CSelectableCore::OutputHandle( THandle * Handle, const char * Data, int Len
|
|||||||
Len = strlen( Data );
|
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
|
// Cannot write to server socket, so Update Remote Client connections individually
|
||||||
ChildHandle = FirstHandle;
|
ChildHandle = FirstHandle;
|
||||||
@@ -1775,7 +2233,7 @@ bool CSelectableCore::Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for auto close (but not on servers)
|
// 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
|
// Close port after timeout
|
||||||
if (Timeout( Handle->LastAction, Handle->CloseTimeout )) {
|
if (Timeout( Handle->LastAction, Handle->CloseTimeout )) {
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Types required for connections
|
// Types required for connections
|
||||||
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, ctForkPipe = 3, ctUNIXserver = 4, ctUNIXclient = 5, ctUNIXremote = 6,
|
||||||
const char ConnectTypeName[][15] = { "None", "SerialPort", "ParallelPort", "Server", "RemoteClient", "Client", "ForkPipe" };
|
ctUDPsock = 7, ctTCPserver = 8, ctTCPremote = 9, ctTCPclient = 10 } EConnectType;
|
||||||
|
const char ConnectTypeName[][20] = { "None", "Serial", "LinePrinter", "ForkPipe", "UNIXserver", "UNIXclient", "UNIXremote", "UDPsock", "TCPserver", "TCPremote", "TCPclient" };
|
||||||
|
|
||||||
typedef enum { csNone = 0, csOpenRequest = 1, csWaitingtoOpen = 2, csOpen = 3, csDataWaiting = 4, csClosed = 5, csFailed = 6 } EConnectState;
|
typedef enum { csNone = 0, csOpenRequest = 1, csWaitingtoOpen = 2, csOpen = 3, csDataWaiting = 4, csClosed = 5, csFailed = 6 } EConnectState;
|
||||||
const char ConnectStateName[][15] = { "None", "OpenRequest", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
const char ConnectStateName[][15] = { "None", "OpenRequest", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
||||||
@@ -84,7 +85,7 @@ struct SHandle {
|
|||||||
long CloseTimeout; // millisecs of no traffic before closing socket
|
long CloseTimeout; // millisecs of no traffic before closing socket
|
||||||
|
|
||||||
// Callback functions
|
// Callback functions
|
||||||
FHandleCallback StateCallback[ 6 ];
|
FHandleCallback StateCallback[ 7 ];
|
||||||
|
|
||||||
// Type specific parameters
|
// Type specific parameters
|
||||||
char * Path; // Port (file)name or Exec path
|
char * Path; // Port (file)name or Exec path
|
||||||
@@ -209,14 +210,18 @@ protected:
|
|||||||
|
|
||||||
int OpenLinePrinterPort( THandle * Handle );
|
int OpenLinePrinterPort( THandle * Handle );
|
||||||
|
|
||||||
// ForkPipe Operations
|
// File Socket Operations
|
||||||
int OpenForkPipe( THandle * Handle );
|
int OpenForkPipe( THandle * Handle );
|
||||||
|
int OpenUNIXserverSocket( THandle * Handle );
|
||||||
|
int OpenUNIXclientSocket( THandle * Handle );
|
||||||
|
int OpenUNIXremoteSocket( THandle * Handle );
|
||||||
|
|
||||||
// Socket Operations
|
// Socket Operations
|
||||||
bool ResolveAddress( THandle * Handle, bool DelayResolve );
|
bool ResolveAddress( THandle * Handle, bool DelayResolve );
|
||||||
int OpenServerSocket( THandle * Handle, bool DelayResolve );
|
int OpenUDPsocket( THandle * Handle, bool DelayResolve );
|
||||||
int OpenRemoteClientSocket( THandle * Handle );
|
int OpenTCPserverSocket( THandle * Handle, bool DelayResolve );
|
||||||
int OpenClientSocket( THandle * Handle, bool DelayResolve );
|
int OpenTCPremoteSocket( THandle * Handle );
|
||||||
|
int OpenTCPclientSocket( THandle * Handle, bool DelayResolve );
|
||||||
|
|
||||||
// Mutual Operations
|
// Mutual Operations
|
||||||
int ReadFromFD( int FD, char * Data, int MaxLen );
|
int ReadFromFD( int FD, char * Data, int MaxLen );
|
||||||
@@ -270,6 +275,7 @@ 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 SetUnixHandle( THandle * Handle, EConnectType Type, const char * FileName );
|
||||||
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay );
|
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, long ResolveDelay );
|
||||||
bool ClearHandle( THandle * Handle );
|
bool ClearHandle( THandle * Handle );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user