Welcome to the Kunena forum!

Tell us and our members who you are, what you like and why you became a member of this site.
We welcome all new members and hope to see you around a lot!
  • Page:
  • 1

TOPIC: Linux TIdTCPServer with OpenSSL and compression

Linux TIdTCPServer with OpenSSL and compression 3 months 1 week ago #14318

Linux TIdTCPServer with OpenSSL and compression

I am testing TIdTCPServer with Linux. The clients are using windows. I have got two problems with OpenSSL and compression. It works fine with Windows. It also works fine if OpenSSL and compression are inactive.

1. When I start the server with OpenSSL (compression inactive) it works. But when I try to stop the server (Active := False), it hangs up.

2. When I start the server with compression (OpenSSL inactive), a Windows client is not able to connect.
unit TCPServer ;

interface

uses
  IdComponent,
  IdContext,
  IdCustomTCPServer,
  IdGlobal,
  IdSocketHandle,
  IdSSL,
  IdStack,
  IdTCPServer,
  System.Classes,
  System.Hash,
  System.SysUtils,
  IdSSLOpenSSL,
  IdCompressionIntercept ;

// *** TTCPServer **************************************************************
type
  TTCPServer = class(TIdTCPServer)

  private
    { Private-Deklarationen }
    FCompression : TIdServerCompressionIntercept ;
    FTLS         : TIdServerIOHandlerSSLOpenSSL ;

    procedure EventOnGetPassword
    ( var iPassword : String ) ;

    procedure EventOnContextCreated
    ( iContext : TIdContext ) ;
    procedure EventOnExecute
    ( iContext : TIdContext ) ;

  protected
    { Protected-Deklarationen }

  public
    { Public-Deklarationen }
    constructor Create
    ( const iOwner : TComponent ) ; overload ;
    destructor  Destroy ; override ;

  published
    { Published-Deklarationen }
  end ;

implementation

// *** Start Create ************************************************************
// *****************************************************************************
constructor TTCPServer.Create
( const iOwner : TComponent ) ;
var
iBinding : TIdSocketHandle ;
begin
{ Inherited }
inherited Create(iOwner) ;

{ Properties }
ReuseSocket := rsTrue ;
{ Compression }
FCompression                  := TIdServerCompressionIntercept.Create(Self) ;
FCompression.CompressionLevel := 9 ;
{ TLS }
FTLS               := TIdServerIOHandlerSSLOpenSSL.Create(Self) ;
FTLS.OnGetPassword := EventOnGetPassword ;
{ Events }
OnContextCreated := EventOnContextCreated ;
OnExecute        := EventOnExecute ;

{ Bind IP }
iBinding             := Bindings.Add ;
iBinding.Port        := 8700 ;
iBinding.ReuseSocket := rsTrue ;
iBinding.IPVersion   := Id_IPv4 ;
iBinding.IP          := '127.0.0.1' ;
{ TLS files linux }
FTLS.SSLOptions.KeyFile  := '/home/thomas/Delphi/sample.key' ;
FTLS.SSLOptions.CertFile := '/home/thomas/Delphi/sample.crt' ;
{ Intercept and IO }
// Intercept := FCompression ;
IOHandler := FTLS ;
end ;
// *** End Create **************************************************************
// *****************************************************************************


// *** Start Destroy ***********************************************************
// *****************************************************************************
destructor TTCPServer.Destroy ;
begin
{ Eigenschaften }
FCompression.DisposeOf ;
FTLS.DisposeOf ;
{ Ererbte Eigenschaften }
inherited Destroy ;
end ;
// *** End Destroy *************************************************************
// *****************************************************************************

// -----------------------------------------------------------------------------

// *** Start EventOnGetPassword ************************************************
// *****************************************************************************
procedure TTCPServer.EventOnGetPassword
( var iPassword : String ) ;
begin
{ Set password }
iPassword := 'aaaa' ;
end ;
// *** End EventOnGetPassword **************************************************
// *****************************************************************************

// -----------------------------------------------------------------------------

// *** Start EventOnContextCreated *********************************************
// *****************************************************************************
procedure TTCPServer.EventOnContextCreated
( iContext : TIdContext ) ;
begin
{ Use TLS }
if iContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase then
  TIdSSLIOHandlerSocketBase(iContext.Connection.IOHandler).PassThrough := False ;
end ;
// *** End EventOnContextCreated ***********************************************
// *****************************************************************************


// *** Start EventOnExecute ****************************************************
// *****************************************************************************
procedure TTCPServer.EventOnExecute
( iContext : TIdContext ) ;
var
iInput : TStringList ;
begin
{ Create list }
iInput := TStringList.Create ;

{ Get data }
iContext.Connection.IOHandler.ReadStrings(iInput,-1,IndyTextEncoding_UTF8) ;
{ Show data }
WriteLn(iInput.Text) ;

{ Disconnect client}
iContext.Connection.Disconnect ;
{ Prevent 100% cpu }
if iContext.Connection.IOHandler.InputBufferIsEmpty = True then
  iContext.Connection.IOHandler.CheckForDataOnSource(10) ;

{ Delete list }
iInput.DisposeOf ;
end ;
// *** End EventOnExecute ******************************************************
// *****************************************************************************
end.
Attachments:

Please Log in or Create an account to join the conversation.

Linux TIdTCPServer with OpenSSL and compression 3 months 1 week ago #14371

I can't answer your questions, since I don't have a Linux system to test with.

I have no idea why deactivating the server would hang if OpenSSL is enabled. You will just have to step into Indy's source code with the debugger to find out what is actually happening.

I can tell you that having Compression enabled should have NO EFFECT WHATSOEVER on the server's ability to accept clients. It ONLY applies when transmitting application data back and forth. So the ONLY way I can see your "compression only" scenario failing is if a client connects and then TIdServerCompressionIntercept.Accept() (which is called by TIdCustomTCPServer.ContextConnected() before it fires the OnConnect event) is raising an exception while trying to prepare a new TIdCompressionIntercept object for the accepted client. You can see if that is the case by using the server's OnException event.

That being said, I see a number of other issues with your code:

- your TTCPServer constructor should be marked as 'override' instead of 'overload'.

- since TTCPServer derives from TIdTCPServer, it should be overriding the virtual ContextCreated() and DoExecute() methods instead of assigning handlers to the OnContextCreated and OnExecute events.

- your TTCPServer destructor is redundant and should be removed completely. The two objects you are disposing in it have the TTCPServer set as their Owner, so they will be freed automatically for you. This also ensures you are not disposing them prematurely if the Server is still active when the destructor is called.

- the OnContextCreated event is the wrong place to activate SSL/TLS. That should be done in the OnConnect event (or overridden DoConnect() method) instead.

- you are unconditionally activating SSL/TLS for every client that connects. Is that what you really want? Does every client expect to perform an SSL/TLS handshake immediately upon connecting?

- in your OnExecute event handler (or in an overridden DoExecute() method), you are not protecting your TStringList object from exceptions. If an exception is raised, you leak the object on Windows (but not on Linux as it uses ARC). But more importantly, you are disconnecting the client after reading some strings from it, and then immediately afterwards you are trying to read more data from the client. You should not be doing that extra reading after disconnect. Your "Prevent 100% cpu" is misguided and wrong and needs to be removed.

Please Log in or Create an account to join the conversation.

  • Page:
  • 1
Moderators: April Anne