[exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog exim…

Top Page
Delete this message
Reply to this message
Author: Philip Hazel
Date:  
To: exim-cvs
Subject: [exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog exim/exim-src/src transport.c exim/exim-test-orig/AutoTest/confs 615 exim/exim-test-orig/AutoTest/log 615 exim/exim-test-orig/AutoTest/scripts
ph10 2005/05/24 15:56:27 BST

  Modified files:
    exim-doc/doc-txt     ChangeLog 
    exim-src/src         transport.c 
  Added files:
    exim-test-orig/AutoTest/confs 615 
    exim-test-orig/AutoTest/log 615 
    exim-test-orig/AutoTest/scripts 615 
    exim-test-orig/AutoTest/stderr 615 
    exim-test-orig/AutoTest/stdout 615 
  Log:
  Reduce the timeout when writing a block has to be done in several
  write() calls.


  Revision  Changes    Path
  1.144     +7 -0      exim/exim-doc/doc-txt/ChangeLog
  1.9       +40 -13    exim/exim-src/src/transport.c
  1.1       +49 -0     exim/exim-test-orig/AutoTest/confs/615 (new)
  1.1       +3 -0      exim/exim-test-orig/AutoTest/log/615 (new)
  1.1       +26 -0     exim/exim-test-orig/AutoTest/scripts/615 (new)
  1.1       +22 -0     exim/exim-test-orig/AutoTest/stderr/615 (new)
  1.1       +21 -0     exim/exim-test-orig/AutoTest/stdout/615 (new)


  Index: ChangeLog
  ===================================================================
  RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
  retrieving revision 1.143
  retrieving revision 1.144
  diff -u -r1.143 -r1.144
  --- ChangeLog    24 May 2005 10:57:10 -0000    1.143
  +++ ChangeLog    24 May 2005 14:56:26 -0000    1.144
  @@ -1,4 +1,4 @@
  -$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.143 2005/05/24 10:57:10 ph10 Exp $
  +$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.144 2005/05/24 14:56:26 ph10 Exp $


   Change log file for Exim from version 4.21
   -------------------------------------------
  @@ -47,6 +47,13 @@
         preserve the sysexits.h value, by assumimg that macro definitions were
         scanned for macro replacements. I have been disabused of this notion,
         so now the code just undefines EX_OK before #including unistd.h.
  +
  +PH/06 There is a timeout for writing blocks of data, set by, e.g. data_timeout
  +      in the smtp transport. When a block could not be written in a single
  +      write() function, the timeout was being re-applied to each part-write.
  +      This seems wrong - if the receiver was accepting one byte at a time it
  +      would take for ever. The timeout is now adjusted when this happens. It
  +      doesn't have to be particularly precise.



Exim version 4.51

  Index: transport.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/transport.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- transport.c    3 May 2005 14:20:01 -0000    1.8
  +++ transport.c    24 May 2005 14:56:27 -0000    1.9
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/transport.c,v 1.8 2005/05/03 14:20:01 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/transport.c,v 1.9 2005/05/24 14:56:27 ph10 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -199,26 +199,42 @@
   transport_write_block(int fd, uschar *block, int len)
   {
   int i, rc, save_errno;
  +int local_timeout = transport_write_timeout;
  +
  +/* This loop is for handling incomplete writes and other retries. In most
  +normal cases, it is only ever executed once. */


   for (i = 0; i < 100; i++)
     {
     DEBUG(D_transport)
       debug_printf("writing data block fd=%d size=%d timeout=%d\n",
  -      fd, len, transport_write_timeout);
  -  if (transport_write_timeout > 0) alarm(transport_write_timeout);
  +      fd, len, local_timeout);


- #ifdef SUPPORT_TLS
- if (tls_active == fd) rc = tls_write(block, len); else
- #endif
+ /* This code makes use of alarm() in order to implement the timeout. This
+ isn't a very tidy way of doing things. Using non-blocking I/O with select()
+ provides a neater approach. However, I don't know how to do this when TLS is
+ in use. */

  -  rc = write(fd, block, len);
  -  save_errno = errno;
  +  if (transport_write_timeout <= 0)   /* No timeout wanted */
  +    {
  +    #ifdef SUPPORT_TLS
  +    if (tls_active == fd) rc = tls_write(block, len); else
  +    #endif
  +    rc = write(fd, block, len);
  +    save_errno = errno;
  +    }


- /* Cancel the alarm and deal with a timeout */
+ /* Timeout wanted. */

  -  if (transport_write_timeout > 0)
  +  else
       {
  -    alarm(0);
  +    alarm(local_timeout);
  +    #ifdef SUPPORT_TLS
  +    if (tls_active == fd) rc = tls_write(block, len); else
  +    #endif
  +    rc = write(fd, block, len);
  +    save_errno = errno;
  +    local_timeout = alarm(0);
       if (sigalrm_seen)
         {
         errno = ETIMEDOUT;
  @@ -230,7 +246,8 @@


     if (rc == len) { transport_count += len; return TRUE; }


- /* A non-negative return code is an incomplete write. Try again. */
+ /* A non-negative return code is an incomplete write. Try again for the rest
+ of the block. If we have exactly hit the timeout, give up. */

     if (rc >= 0)
       {
  @@ -238,7 +255,7 @@
       block += rc;
       transport_count += rc;
       DEBUG(D_transport) debug_printf("write incomplete (%d)\n", rc);
  -    continue;
  +    goto CHECK_TIMEOUT;   /* A few lines below */
       }


     /* A negative return code with an EINTR error is another form of
  @@ -248,7 +265,7 @@
       {
       DEBUG(D_transport)
         debug_printf("write interrupted before anything written\n");
  -    continue;
  +    goto CHECK_TIMEOUT;   /* A few lines below */
       }


     /* A response of EAGAIN from write() is likely only in the case of writing
  @@ -259,6 +276,16 @@
       DEBUG(D_transport)
         debug_printf("write temporarily locked out, waiting 1 sec\n");
       sleep(1);
  +
  +    /* Before continuing to try another write, check that we haven't run out of
  +    time. */
  +
  +    CHECK_TIMEOUT:
  +    if (transport_write_timeout > 0 && local_timeout <= 0)
  +      {
  +      errno = ETIMEDOUT;
  +      return FALSE;
  +      }
       continue;
       }



Index: 615
====================================================================
# Exim test configuration 615

# Macros are set externally in order to get the path
# of the Exim that is being tested, and the directory
# in which the test data lives.

exim_path = EXIM_PATH
primary_hostname = myhost.test.ex
spool_directory = DIR/spool

# ----- Main settings -----

acl_smtp_rcpt = accept


# ----- Routers -----

begin routers

  r0:
    driver = redirect
    senders = :
    data = /dev/null
    user = CALLER   


  r1:
    driver = accept
    transport = t1 



# ----- Transports -----

begin transports

  t1:
    driver = smtp
    hosts = 127.0.0.1
    port = 1225 
    allow_localhost 
    data_timeout = 1s 



# ----- Retry -----

begin retry

* * F,1d,1h

# End

Index: 615
====================================================================
1999-03-02 09:44:33 10HmaX-0005vi-00 <= ph10@??? U=ph10 P=local-smtp S=1600260
1999-03-02 09:44:33 10HmaX-0005vi-00 SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after sending data block (188349 bytes written): Connection timed out
1999-03-02 09:44:33 10HmaX-0005vi-00 == def@pqr R=r1 T=t1 defer (110): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after sending data block (188349 bytes written)

Index: 615
====================================================================
0 Timeout while actually writing the data for a message
server 1225
220 Welcome
EHLO
250 Hi
MAIL FROM
250 OK
RCPT TO
250 OK
DATA
354 SEND
*sleep 3
****
0
write test-data 20000x80
mail from:<abc@xyz>
RCPT TO:<def@pqr>
DATA
++++
.
quit
****
0
exim -v -odi -bs <test-data
****
no_msglog_check

  Index: 615
  ====================================================================
  LOG: smtp_connection MAIN
    SMTP connection from ph10
  LOG: MAIN
    <= ph10@??? U=ph10 P=local-smtp S=1600260
  delivering 10HmaX-0005vi-00
  Connecting to 127.0.0.1 [127.0.0.1]:1225 ... connected
    SMTP<< 220 Welcome
    SMTP>> EHLO myhost.test.ex
    SMTP<< 250 Hi
    SMTP>> MAIL FROM:<ph10@???>
    SMTP<< 250 OK
    SMTP>> RCPT TO:<def@pqr>
    SMTP<< 250 OK
    SMTP>> DATA
    SMTP<< 354 SEND
    SMTP>> writing message and terminating "."
  LOG: MAIN
    SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after sending data block (188349 bytes written): Connection timed out
  LOG: MAIN
    == def@pqr R=r1 T=t1 defer (110): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after sending data block (188349 bytes written)
  LOG: smtp_connection MAIN
    SMTP connection from ph10 closed by QUIT


Index: 615
====================================================================
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250 OK
250 Accepted
354 Enter message, ending with "." on a line by itself
250 OK id=10HmaX-0005vi-00
221 myhost.test.ex closing connection

******** SERVER ********
Listening on port 1225 ...
Connection request from [127.0.0.1]
220 Welcome
EHLO myhost.test.ex
250 Hi
MAIL FROM:<ph10@???>
250 OK
RCPT TO:<def@pqr>
250 OK
DATA
354 SEND
*sleep 3
End of script