Indy 10 finally with Delphi2005 released, but Indy Suite in my impression is always complex and bug constantly, to tell the truth, not to look at his set of components of the face, I still like VCL native socket components, concise, clear. Indy9 developed to the INDY10 almost completely incompatible, alas ah. Anyway When using the Idtcpserver component, he found his vulnerability, his onconnec,onexecute,ondisconnect and other events are executed in other threads, usually this is not a problem, but in a special situation can cause problems, If other parts of the program write a problem, there will be a vulnerability.
The loophole I found was that I released a ListView item in the OnDisconnect event, that is, when a client leaves, the ListView corresponding item on the interface is deleted. Normal situation does not have any problems, however, if you do not disconnect directly shut down the program will be dead, in fact, I in the program in the form of the Closequery event, in this event I closed the connection, but, no effect, only in the program manual point mouse off will not die, the problem is where?
The problem here is that the ListView is a standard component of Windows, and releasing one of his item is done through the message, that is, I am sending a message to the main thread's window in OnDisconnect and waiting to be returned. And what is the main thread doing at this point? Because it is the main thread-triggered disconnect, he waits for the service thread of the port to hang, so that a deadlock occurs, and the problem is that the main thread waits for the service thread to suspend the processing code improperly, and it should theoretically wait for the message to be processed simultaneously. The original code looks like this
Procedure Tidschedulerofthread.terminateyarn (Ayarn:tidyarn);
Var
Lyarn:tidyarnofthread;
Begin
Lyarn: = Tidyarnofthread (Ayarn);
If LYarn.Thread.Suspended then BEGIN//Determine if hang, suspend to release thread
If suspended, was created but never started
IE waiting on connection accept
LYarn.Thread.Free;
Freeandnil (Lyarn);
End ELSE begin
is already running and would free itself
LYarn.Thread.Stop; Endless calls to the stop procedure without processing any messages and synchronization events
Dont Free the yarn. The thread frees it (Idthread.pas)
End
End
Its top-level caller, endlessly judging the number of service threads, and then endlessly calling the above function, the caller's original code is as follows
Procedure Tidtcpserver.terminateallthreads;
Var
I:integer;
Begin
Todo:reimplement Support for Terminatewaittimeout
//bgo:find out why terminateallthreads are sometimes called multiple times
//kudzu:its because of not Ifications. It calls shutdown when the Scheduler are
//set to nil and then again on destroy.
If contexts <> nil then begin
with Contexts.locklist do try
& nbsp; for I: = 0 to Count-1 does begin
//Dont call disconnect with TR Ue. Otheriwse it frees the Iohandler and the thread
//is still running which of Ten causes AVs and other.
Tidcontext (Items[i]). Connection.disconnect (False);
end;
finally contexts.unlocklist; end;
End;
Scheduler may nil during destroy which calls Terminateallthreads
This happens with explicit schedulers
If Scheduler <> Nil then BEGIN
Scheduler.terminateallyarns;
End
End
To tell you the truth, I don't understand. Indy Thread object is also the meaning of the complex model of stop and start, and it is very easy to problem, the simple threading model is more reliable and practical.
The method of modification is simple, but given the compatibility of Linux and other platforms, it is a bit more complex to isolate the decomposition hierarchy. is to add a public method ProcessMessages in the Idthread class, and then call it in Terminateyarn. The code is as follows
Procedure Tidthread.processmessages;
Begin
{$IFDEF MSWindows}
If GetCurrentThreadID = Mainthreadid Then
Begin
Checksynchronize;
Application.processmessages;
End
{$ENDIF}
{$IFDEF LINUX}
If GetCurrentThreadID = Mainthreadid Then
Begin
Checksynchronize (1000);
End
{$ENDIF}
End
Procedure Tidschedulerofthread.terminateyarn (Ayarn:tidyarn);
Var
Lyarn:tidyarnofthread;
Begin
Lyarn: = Tidyarnofthread (Ayarn);
If LYarn.Thread.Suspended then BEGIN
If suspended, was created but never started
IE waiting on connection accept
LYarn.Thread.Free;
Freeandnil (Lyarn);
End ELSE begin
is already running and would free itself
LYarn.Thread.Stop;
LYarn.Thread.ProcessMessages; Processing has been added here.
Dont Free the yarn. The thread frees it (Idthread.pas)
End
End
Tidthread Unit added uses
{$IFDEF MSWindows}
Windows, Forms,
{$ENDIF}
This procedure is normal.
Although in theory, accessing VCL components in other threads should use the thread synchronization method, in this case the thread synchronization method cannot be used because the worker wrapper is too deep, in this case even using the thread synchronization method to access the VCL is useless, Because the open messages and thread synchronization events for the main thread are not checked at all in the program that is waiting for the thread to end (Delphi7 later versions of thread synchronization methods use event events as the synchronous method, Delphi7 will deadlock before using message synchronization).
In fact, the VCL does not enforce the main thread access, his description is this, it requires that at any time only one thread access to the VCL code (different threads access irrelevant VCL code snippet is not a problem), so, do not use the thread synchronization method to access the VCL is also possible, However, other methods are used to ensure that access is unique, such as the use of critical sections.
Here are some tips for using SSL.
Open source to my impression is really getting worse, earlier to deal with MySQL version compatibility is unbearable, incomplete documentation, version differences significantly, different versions of the external interface inconsistent, even do not know to maintain backward compatibility, the sample is small, nothing is to call you to see the source program, To tell the truth most of the time to do development which has so much time to People's source program Ah, a while Pascal, a while C + +, a while in Pascal do not hit; end, a moment in C + + wrote Begin end, tired ah.
The SSL components in Indy are Idserveriohandlersslopenssl and Idssliohandlersocketopenssl, the previous one used on the server, and the latter one used on the client.
Just start with, can't find DLL, I think we all met, read a half-day e-wen, oh, he used OpenSSL, which is what? Download a bar, the original is open source project, or multi-platform, I day, want me to install Perl generate Mack file, also install VC6 to compile into binary code, halo, I just 2 dll, not so toss me. Forget it, go find it again, huh? Have compiled a good download, good. There is a new version of the 0.9.7c, but more than my source code of 0.9.8 is a little bit low, forget it, download complete, copy dll past, I day, version is incorrect, DLL external interface function is incorrect. Which version of the Indy? Indy official on the internet for a long while he did not say that his indy10 based on which version, the quality of this component supplier can be seen. No, download a demo,demo contains the two DLLs, good, copy the past, can use, finally started.
Started, it does not work, see Help, Indy help nothing, some humble to incredibly only a word, this is a string type of attribute, this to she say? Do not have to look at the demo (I now have a little understanding of the meaning of open source), so many years to develop a good habit of the cost, used to do development, the use of new components, the first is to see the official help, Microsoft's that help is called detailed Ah, finished, now the first thing is to see the demo, still do not know I don't know if I can cover all the content. See a half-day example, the original certificate file, I am stupid enough, SSL no certificate how to play? Certificate? What to do? For a long while, I should need a self-signed root certificate, then need a secondary certificate, and finally the key file. In fact, I just need a self-signed certificate to do it. What the hell? There is no tool in Windows that can generate a new certificate, and IIS has one, but the certificate file does not know where to hide it. Had to use OpenSSL to generate a new certificate.
Make a day, finally see understand the key directive of OPENSLL, approximate structure has a vague impression, first produce a key file, and then use this key file to generate a self-signed certificate, this certificate can be used as root certificate, more methods do not know, key file to use DES encryption, With other encryption, Indy is not recognized. CRT to use X509 protocol. The specific OpenSSL instructions are as follows, more than 10 years useless DOS interface, it seems to practice fingering.
Generate a key, of course, first start OpenSSL, a DOS interface, professional point, command line interface, or called xxxxxx
Openssl>genrsa-des3-out-voiceservice.key 1024
The following is the response of OpenSSL
Loading ' screens ' into random state-done
Generating RSA private key, 1024x768 bit long modulus
............................................................................++++++
........++++++
E is 65537 (0x10001)
Enter Pass phrase for-ca.key:123456
Verifying-enter Pass phrase for-ca.key:123456
123456 is the password you entered, the higher version of OpenSSL will not be displayed.
Generate a self-signed certificate
Req-new-x509-days 3650-key voiceservice.key-out voiceservice.crt-config openssl.cnf
Note that the openssl.cnf file is a configuration file that you can edit yourself with edit, not with Notepad. But generally with the, compared to the bastard you downloaded the compiled OpenSSL does not have this file, only download the source code, copy to the directory of OpenSSL, or other directories you like.
The response of OpenSSL
Enter Pass phrase for Ca.key:
You is about-to is asked to-enter information that'll be incorporated
into your certificate request.
What's about-to-enter is called a distinguished Name or a DN.
There is quite a few fields but can leave some blank
For some fields there would be a default value,
If you enter '. ', the field would be a left blank.
-----
Country Name (2 letter code) [AU]:CN
State or province name (full name) [Some-state]:zj
Locality Name (eg, city) []:hz
Organization Name (eg, company) [Internet widgits Pty Ltd]:voiceservice
Organizational Unit Name (eg, section) []:voiceservice
Common name (eg, YOUR name) []:voiceservice
Email Address []:[email protected]
Many are you fill in the content, remember that China's country abbreviation is CN, I checked for a long, I am enough benzene ah, the provinces and cities abbreviations casually write, the following is also casually write.
2 files will be generated after the fix
Voiceservice.key and VOICESERVICE.CRT
Voiceservice.crt This file copy a modified suffix to VOICESERVICE.PEM, in fact, no modification is OK.
Then copy to the directory where the server program is located, the program segment loaded in Indy, and I'll modify it here in the form's Create event
Var
appdir:string;
Begin
Users:=tusers.create;
appdir:= Extractfilepath (application.exename);
idserveriohandlersslopenssl1.ssloptions.keyfile:= appdir + ' Voiceservice.key ';
idserveriohandlersslopenssl1.ssloptions.certfile:= appdir + ' voiceservice.crt ';
idserveriohandlersslopenssl1.ssloptions.rootcertfile:= appdir + ' VOICESERVICE.PEM ';
These file paths can not be used relative paths, only the absolute path, enough to fuck it.
Fill in the password in the Ongetpassword event of Idserveriohandlersslopenssl
password:=123456;
And then you're ready to work.
The sense of open source, in the open source community is the easiest to find when the boss feeling, because there is no official documents, no examples, and some are only familiar with the source code.
From an industrial standpoint, complete documentation and proven paradigms are the cornerstone of technological progress, not the source code.
The open source community has heroes, but no engineers, there are ideas, but no norms.
Business software seems unlikely to disappear, as does the open source community.
Http://www.cnblogs.com/qiubole/archive/2006/04/06/368229.html
Delphi Components Indy 10 Idtcpserver revision and SSL usage experience