Solved

Indy 10 and sendmail configuration

Posted on 2007-11-22
18
2,307 Views
Last Modified: 2010-04-21
Hello,
I use the latest indy10 with Kylix 3 to send emails. The program I developed is a CGI (CGI stand-alone). But then when the CGI send mails, it turns out that at times the CGI crashes, the mail is not sended, and released following the timeout on the execution of the program.

From a script (bash), which runs the CGI every 20 seconds here is the result:
19 h48 --> 19h52: 11 mails
20 h53 --> 20h59: 21 mails
22 h00 --> 22h07: 21 mails
23 h08 --> 23:14: 21 mails
...
And so on over 1000 mails

In short, and apart from the start with the mailing of 11 e-mails:
- 21 mails are sent
- The 22nd mail is waiting (I do not know why)
- There is therefore a Timeout (seen in the log file / var / log / maillog) after 1:01
- 21 new e-mails are sent
- The 22nd mail is pending during 1:01
...

This scenario occurs in extremely regularly. One could think of a bad sendmail configuration on the server. But then why sends mail by the mail function of php (a site is hosted on the server) has never had a problem?

Here is the test code for the CGI :

var
    SMTP : TIdSMTP;
    MailMessage: TIdMessage;
    aHost, aUserName, aPassWord, cIniSmtpFileName, aFrom, aTo: string;
    aPort: integer;
    IniFile: TIniFile;
begin
  try
    cIniSmtpFileName := 'smtp.kp';

    if FileExists(ApplicationPath + cIniSmtpFileName) then
    begin
      IniFile := TIniFile.Create(ApplicationPath + cIniSmtpFileName);
      try
        aHost := IniFile.ReadString('SmtpConfig', 'Host', 'localhost');
        aPort := IniFile.ReadInteger('SmtpConfig', 'Port', 25);
        aFrom := IniFile.ReadString('SmtpConfig', 'From', 'nj@keepcore.com');
        aTo := IniFile.ReadString('SmtpConfig', 'To', 'jardillier@gmail.com');
      finally
        FreeAndNil(IniFile);
      end;
    end;

    SMTP := TIdSMTP.Create(Self);
    SMTP.Host := aHost;
    SMTP.Port := aPort;
    MailMessage := TIdMessage.Create;
    MailMessage.Clear;
    MailMessage.From.Address := aFrom;
    MailMessage.Recipients.EMailAddresses := aTo;

    MailMessage.Subject := 'Un mail pour vous avertir';
    MailMessage.Body.Text := 'Blalala bla bla blabla bla';

  except
    on E:Exception do
      LogException(E, 'Tsendemail.Execute Message');
  end;

  try
    SMTP.Connect;
    try
      SMTP.Send(MailMessage);
    finally
      SMTP.Disconnect;
    end;
  except
    on E:Exception do
      LogException(E, 'Tsendemail.Execute Send');
  end;

Thanks
0
Comment
Question by:KCTeam
  • 10
  • 8
18 Comments
 
LVL 28

Accepted Solution

by:
ciuly earned 250 total points
Comment Utility
indy does not use sendmail. your indy-cgi acts like sendmail.

basically, sendmail connects to the smtp server and sends the email.

your cgi should do the same: connect to the smtp server and send the email.

my question is: if  if FileExists(ApplicationPath + cIniSmtpFileName) then returns false, what values will the cgi use? just a "minor" bug ;)

also, you should move the second try/except in the first one, after the mail message has been created and filled. because if there is an exception, there is no sense in trying to connect and send the message (that also will create an exception in practically all cases).

so the question is: what smtp sever are you using? the value of host, which defaults to localhost. are you running a smtp server on localhost? if so, is it properly configured? what about network connections? does the smtp server listen on localhost:25 or jsut on the outbound ip? is the firewall blocking the connection? etc.

there are too many questions here. but generaly, we need an error in order to correctly track down the problem. at least a timeout error somewhere (at connect, at send, etc)
0
 

Author Comment

by:KCTeam
Comment Utility
Thanks for your answer,
i use for the host of the smtp 'localhost' and for the port '25'.
For the configuration of the SMTP i'm confused, i do not really know which kind of stuff i have to check first. Moreover, i only have the command line access to my server.
I will study and work more the smtp configuration. As the system is Fedora Core 5, the smtp should be the default one, i'll check that.

The error i had in the file maillog was :
Nov 22 14:19:05 <xxxxx> sendmail[4212]: lAMCJ1nI004212: SYSERR(root): collect: read timeout on connection from localhost.localdomain, from=<opache@kcdeditest.com>
Nov 22 14:19:05 <xxxxx> sendmail[4212]: lAMCJ1nI004212: from=<opache@kcdeditest.com>, size=5, class=0, nrcpts=1, proto=ESMTP, daemon=MTA, relay=localhost.localdomain [127.0.0.1]
0
 
LVL 28

Assisted Solution

by:ciuly
ciuly earned 250 total points
Comment Utility
netstat will show you if there is a smtp server running on port 25 and will also tell you on what interfaces it listents. if there isn't one .. that's your problem.
0
 

Author Comment

by:KCTeam
Comment Utility
if i do 'netstat -a' i see:
tcp  0  0 *.smtp  *:*  LISTEN
0
 
LVL 28

Assisted Solution

by:ciuly
ciuly earned 250 total points
Comment Utility
well, that means that the smtp server is listening on all interfaces on the port configured as beeing the smtp port in the services file, which is almost always 25.
so that should be ok.

can you please put an else for the
  if FileExists(ApplicationPath + cIniSmtpFileName) then
and set default values? jsut to be on the safe side ;)
and move the second try/except in the first one, after the mail message has been created and filled, as I said at first time.

then, change the following:
 MailMessage.From.Address := aFrom;
to
 MailMessage.From.text := aFrom;

and add a line
  MailMessage.Sender.text := aFrom;

that should make sure the problem is not because of bad code.

last resort is to send the email without using an inermediary smtp server, but relay it to the recipient smtp server. You have an example here: http://www.ciuly.com/delphi/indy/sendMail/index.html

but if you have multiple recipients, you will have to modify that example :)
0
 

Author Comment

by:KCTeam
Comment Utility
I had already changed the code, and now i add your new advice :

var
    SMTP : TIdSMTP;
    MailMessage: TIdMessage;
    aHost, aUserName, aPassWord, cIniSmtpFileName, aFrom, aTo: string;
    aPort: integer;
    IniFile: TIniFile;
begin
  try
    cIniSmtpFileName := 'smtp.kp';
    if FileExists(ApplicationPath + cIniSmtpFileName) then
    begin
      IniFile := TIniFile.Create(ApplicationPath + cIniSmtpFileName);
      try
        aHost := IniFile.ReadString('SmtpConfig', 'Host', 'localhost');
        aPort := IniFile.ReadInteger('SmtpConfig', 'Port', 25);
        aFrom := IniFile.ReadString('SmtpConfig', 'From', 'xx@xx.com');
        aTo := IniFile.ReadString('SmtpConfig', 'To', 'xx@xx.com');

        SMTP := TIdSMTP.Create(self);
        SMTP.Host := aHost;
        SMTP.Port := aPort;

        MailMessage := TIdMessage.Create;
        MailMessage.From.Text := aFrom;
        MailMessage.Sender.Text := aFrom;
        MailMessage.Recipients.EMailAddresses := aTo;

        MailMessage.Subject := 'Un mail pour vous avertir';
        MailMessage.Body.Text := 'Blalala bla bla blabla bla';

        SMTP.Connect;
        SMTP.Send(MailMessage);
      finally
        FreeAndNil(IniFile);
        SMTP.Disconnect;
        SMTP.Free;
      end;
    end;
  except
    on E:Exception do
      LogException(E, 'Tsendemail.Execute 1');
  end;
  Response.content := '<html><body>Hello World !!!</body></html>';

I will make the test, with this code.

I have to mention also that i installed postfix-2.4.1-2 by rpm,
made a 'alternatives --config mta' and chose the /usr/sbin/sendmail.postfix program,
and reload postfix.
I ran a bash script to execute 1000 times the CGI. And good surprise, all of them were sent and recieved in my mailbox. As i'm not sure that it will always be like that, i will make again this test with the code i show you above.
0
 

Author Comment

by:KCTeam
Comment Utility
with the code describe above, I sent 1000 emails, without any problems. As a test, I sent 2000 emails, then, 3 of them were not send with the exception :
An exception has occurred : EIdSMTPReplyError=kcdeditest.localdomain Error: timeout exceeded

The file maillog contains several error messages (more than 3)
 host gmail-smtp-in.l.google.com[72.14.221.27] refused to talk to me:    Our system has detected an unusual amount of unsolicited xxxx mail originating from your IP address. To protect our xxxx users from spam, mail sent from your IP address has been xxxx temporarily blocked. Please visit xxxx http://www.google.com/mail/help/bulk_mail.html to review xxxx our Bulk Email Senders Guidelines.

and also:
Nov 23 13:35:22 xxxx postfix/qmgr[10562]: 9439213003D: from=<xxx@xxx.com>, size=1310, nrcpt=1 (queue active)

It seems that it works.
Here, the configuration :
postfix/scache[24476]: statistics: max simultaneous domains=1 addresses=2 connection=20
0
 
LVL 28

Assisted Solution

by:ciuly
ciuly earned 250 total points
Comment Utility
the second error is obvious, I guess :)
the 3rd I don't know what to make out of it. I never saw that one before (or anything similar).

I would also like to apologies for my bad memory: I totally forgot that sendmail is actualy a very old email server :D so my first post is partially wrong. I was induced in error by me having for about 2-3 years otehr email servers that have a sendmail script that actually sends email and the name is probably kept like that for backward compatibility with the sendmail smtp server that came (comes?) by default with some of the linux distros.

again, sorry.

regarding the timeout, it could be that there were too many attempts to send an email in the same time. you could try and limit the number of concurrent executions of the cgi. unfortunatly I don't have any ideas what a good value that would be as I never needed to find out.
0
 

Author Comment

by:KCTeam
Comment Utility
Thanks for all your help ;)
Sometimes, the send of the email is freezed, and i dont know why, do you know how to configure the smtp, at least the delay of a try ?
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 28

Assisted Solution

by:ciuly
ciuly earned 250 total points
Comment Utility
that depends on the smtp server. I for example am using xmail and there is no such settings to my knowledge.
probably a good idea would be to post on teh forum/group of the smtp server you are using (postfix, as I understood to be your last installed server)
0
 

Author Closing Comment

by:KCTeam
Comment Utility
Many thanks for your help
0
 

Author Comment

by:KCTeam
Comment Utility
Hello,
Just a last question ... sometines i have this exception, when the program try to send an email:
 An exception has occurred : EInvalidOp=Invalid floating point operation

if this exception occurs, it is catched and then i try to disconnect the smtp, before a free. It appears that the smtp can not disconnect. The only way, except to kill it, is to wait the timeout of cgi execution.
Due you have any ideas ? May i have to free the smtp without disconnect it before ? I'l try.
0
 
LVL 28

Expert Comment

by:ciuly
Comment Utility
it's a weird behaviour. It might be a bug in the indy smtp, I've seen (and fixed) a few the past few weeks. you should be able to disconnect the socket at any time. try to force the disconnect on the socket itself (idsmtp.socket.disconect or disconnectsocket or something like that. I don't have an ide open right now).
0
 

Author Comment

by:KCTeam
Comment Utility
If i use a idsmtp.socket.close or idsmtp.socket.closegracefully, i lost the connexion, and my program stop.
0
 
LVL 28

Expert Comment

by:ciuly
Comment Utility
well .. that's what should happen in a disconnect, no? loose the connection.
0
 

Author Comment

by:KCTeam
Comment Utility
Yes, but the problem is that the cgi finish as it is killed :

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
 root@localhost and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
<hr>

in the error.log of apache, there is:
Premature end of script headers: kp_synchro_debug.exe
0
 
LVL 28

Expert Comment

by:ciuly
Comment Utility
that can mean some other bug. maybe you are not catching a connection closed gracefully? make sure your code is well protected against unhandled exceptions.
0
 

Author Comment

by:KCTeam
Comment Utility
Hello,
many thanks for your help.
I used indy-10.2.0.3, and i just tried to use indy-10.2.0.1, and now i do not have any problem anymore.
All of these problems seem to be due to bugs in the last version of Indy (use with Kylix).
Best regards
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now