Add queue_only_load_latch.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 27 Jun 2007 11:01:51 +0000 (11:01 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Wed, 27 Jun 2007 11:01:51 +0000 (11:01 +0000)
16 files changed:
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
src/src/daemon.c
src/src/exim.c
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/macros.h
src/src/readconf.c
test/confs/0160
test/confs/0561 [new file with mode: 0644]
test/log/0561 [new file with mode: 0644]
test/scripts/0000-Basic/0561 [new file with mode: 0644]
test/stderr/0561 [new file with mode: 0644]
test/stdout/0561 [new file with mode: 0644]

index 31bd94a..2306cf4 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.519 2007/06/26 11:16:54 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.520 2007/06/27 11:01:51 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -74,6 +74,8 @@ PH/12 Added +ignore_defer and +include_defer to host lists.
 PH/13 Installed PCRE version 7.2. This needed some changes because of the new
       way in which PCRE > 7.0 is built.
 
+PH/14 Implemented queue_only_load_latch.
+
 
 Exim version 4.67
 -----------------
index f61b1f7..0dc3660 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.153 2007/06/26 09:23:34 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.154 2007/06/27 11:01:51 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -82,6 +82,11 @@ Version 4.68
     +ignore_unknown and +include_unknown. These options should be used with
     care, probably only in non-critical host lists such as whitelists.
 
+ 8. There's a new option called queue_only_load_latch, which defaults true.
+    If set false when queue_only_load is greater than zero, Exim re-evaluates
+    the load for each incoming message in an SMTP session. Otherwise, once one
+    message is queued, the remainder are also.
+
 
 Version 4.67
 ------------
index 2bd046b..6c28ebd 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.32 2007/04/11 15:26:10 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.33 2007/06/27 11:01:51 ph10 Exp $
 
 LISTS OF EXIM OPTIONS
 ---------------------
@@ -126,6 +126,7 @@ check_spool_space                    integer         0             main
 check_string                         string          "From "       appendfile        3.03
                                                      unset         pipe              3.03
 check_srv                            string*         unset         dnslookup         4.31
+client_condition                     string*         unset         authenticators    4.68
 client_ignore_invalid_base64         boolean         false         plaintext         4.61
 client_name                          string*         +             cram_md5          3.10
 client_secret                        string*         unset         cram_md5          3.10
@@ -398,6 +399,7 @@ queue_list_requires_admin            boolean         true          main
 queue_only                           boolean         false         main
 queue_only_file                      string          unset         main              2.05
 queue_only_load                      fixed-point     unset         main
+queue_only_load_latch                boolean         true          main              4.68
 queue_only_override                  boolean         true          main              4.21
 queue_run_in_order                   boolean         false         main              1.70
 queue_run_max                        integer         5             main
index e844403..55701f0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/daemon.c,v 1.23 2007/03/14 12:15:56 ph10 Exp $ */
+/* $Cambridge: exim/src/src/daemon.c,v 1.24 2007/06/27 11:01:51 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -241,7 +241,7 @@ subprocess because it might take time. */
 
 if (smtp_load_reserve >= 0)
   {
-  load_average = os_getloadavg();
+  load_average = OS_GETLOADAVG();
   if (smtp_reserve_hosts == NULL && load_average > smtp_load_reserve)
     {
     DEBUG(D_any) debug_printf("rejecting SMTP connection: load average = %.2f\n",
@@ -365,6 +365,7 @@ if (pid == 0)
   int old_pool = store_pool;
   int save_debug_selector = debug_selector;
   BOOL local_queue_only;
+  BOOL session_local_queue_only;
   #ifdef SA_NOCLDWAIT
   struct sigaction act;
   #endif
@@ -413,7 +414,7 @@ if (pid == 0)
   /* Initialize the queueing flags */
 
   queue_check_only();
-  local_queue_only = queue_only;
+  session_local_queue_only = queue_only;
 
   /* Close the listening sockets, and set the SIGCHLD handler to SIG_IGN.
   We also attempt to set things up so that children are automatically reaped,
@@ -457,13 +458,15 @@ if (pid == 0)
   if (debug_daemon) debug_selector = 0;
 
   /* If there are too many child processes for immediate delivery,
-  set the local_queue_only flag, which is initialized from the
+  set the session_local_queue_only flag, which is initialized from the
   configured value and may therefore already be TRUE. Leave logging
-  till later so it will have a message id attached. */
+  till later so it will have a message id attached. Note that there is no
+  possibility of re-calculating this per-message, because the value of
+  smtp_accept_count does not change in this subprocess. */
 
   if (smtp_accept_queue > 0 && smtp_accept_count > smtp_accept_queue)
     {
-    local_queue_only = TRUE;
+    session_local_queue_only = TRUE;
     queue_only_reason = 1;
     }
 
@@ -550,26 +553,37 @@ if (pid == 0)
     store_reset(reset_point);
 
     /* If queue_only is set or if there are too many incoming connections in
-    existence, local_queue_only will be TRUE. If it is not, check whether we
-    have received too many messages in this session for immediate delivery. If
-    not, and queue_only_load is set, check that the load average is below it.
-    Note that, once set, local_queue_only remains set for any subsequent
-    messages on the same SMTP connection. This is a deliberate choice; even
-    though the load average may fall, it doesn't seem right to deliver later
-    messages on the same call when not delivering earlier ones. */
-
-    if (!local_queue_only)
+    existence, session_local_queue_only will be TRUE. If it is not, check
+    whether we have received too many messages in this session for immediate
+    delivery. */
+
+    if (!session_local_queue_only &&
+        smtp_accept_queue_per_connection > 0 &&
+        receive_messagecount > smtp_accept_queue_per_connection)
       {
-      if (smtp_accept_queue_per_connection > 0 &&
-          receive_messagecount > smtp_accept_queue_per_connection)
-        {
-        local_queue_only = TRUE;
-        queue_only_reason = 2;
-        }
-      else if (queue_only_load >= 0)
+      session_local_queue_only = TRUE;
+      queue_only_reason = 2;
+      }
+
+    /* Initialize local_queue_only from session_local_queue_only. If it is not
+    true, and queue_only_load is set, check that the load average is below it.
+    If local_queue_only is set by this means, we also set if for the session if
+    queue_only_load_latch is true (the default). This means that, once set,
+    local_queue_only remains set for any subsequent messages on the same SMTP
+    connection. This is a deliberate choice; even though the load average may
+    fall, it doesn't seem right to deliver later messages on the same call when
+    not delivering earlier ones. However, the are special circumstances such as
+    very long-lived connections from scanning appliances where this is not the
+    best strategy. In such cases, queue_only_load_latch should be set false. */
+
+    local_queue_only = session_local_queue_only;
+    if (!local_queue_only && queue_only_load >= 0)
+      {
+      local_queue_only = (load_average = OS_GETLOADAVG()) > queue_only_load;
+      if (local_queue_only)
         {
-        local_queue_only = (load_average = os_getloadavg()) > queue_only_load;
-        if (local_queue_only) queue_only_reason = 3;
+        queue_only_reason = 3;
+        if (queue_only_load_latch) session_local_queue_only = TRUE;
         }
       }
 
index 3a89d8b..12f61a2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.56 2007/06/19 14:41:31 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.57 2007/06/27 11:01:51 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1291,6 +1291,7 @@ BOOL one_msg_action = FALSE;
 BOOL queue_only_set = FALSE;
 BOOL receiving_message = TRUE;
 BOOL sender_ident_set = FALSE;
+BOOL session_local_queue_only;
 BOOL unprivileged;
 BOOL removed_privilege = FALSE;
 BOOL verify_address_mode = FALSE;
@@ -3643,7 +3644,7 @@ if (receiving_message &&
         (is_inetd && smtp_load_reserve >= 0)
       ))
   {
-  load_average = os_getloadavg();
+  load_average = OS_GETLOADAVG();
   }
 #endif
 
@@ -4528,11 +4529,11 @@ else
     sender_address);
   }
 
-/* Initialize the local_queue-only flag (this will be ignored if mua_wrapper is
-set) */
+/* Initialize the session_local_queue-only flag (this will be ignored if
+mua_wrapper is set) */
 
 queue_check_only();
-local_queue_only = queue_only;
+session_local_queue_only = queue_only;
 
 /* For non-SMTP and for batched SMTP input, check that there is enough space on
 the spool if so configured. On failure, we must not attempt to send an error
@@ -4891,27 +4892,36 @@ while (more)
     }
 
   /* Else act on the result of message reception. We should not get here unless
-  message_id[0] is non-zero. If queue_only is set, local_queue_only will be
-  TRUE. If it is not, check on the number of messages received in this
-  connection. If that's OK and queue_only_load is set, check that the load
-  average is below it. If it is not, set local_queue_only TRUE. Note that it
-  then remains this way for any subsequent messages on the same SMTP connection.
-  This is a deliberate choice; even though the load average may fall, it
-  doesn't seem right to deliver later messages on the same call when not
-  delivering earlier ones. */
-
-  if (!local_queue_only)
+  message_id[0] is non-zero. If queue_only is set, session_local_queue_only
+  will be TRUE. If it is not, check on the number of messages received in this
+  connection. */
+
+  if (!session_local_queue_only &&
+      smtp_accept_queue_per_connection > 0 &&
+      receive_messagecount > smtp_accept_queue_per_connection)
     {
-    if (smtp_accept_queue_per_connection > 0 &&
-        receive_messagecount > smtp_accept_queue_per_connection)
-      {
-      local_queue_only = TRUE;
-      queue_only_reason = 2;
-      }
-    else if (queue_only_load >= 0)
+    session_local_queue_only = TRUE;
+    queue_only_reason = 2;
+    }
+
+  /* Initialize local_queue_only from session_local_queue_only. If it is false,
+  and queue_only_load is set, check that the load average is below it. If it is
+  not, set local_queue_only TRUE. If queue_only_load_latch is true (the
+  default), we put the whole session into queue_only mode. It then remains this
+  way for any subsequent messages on the same SMTP connection. This is a
+  deliberate choice; even though the load average may fall, it doesn't seem
+  right to deliver later messages on the same call when not delivering earlier
+  ones. However, there are odd cases where this is not wanted, so this can be
+  changed by setting queue_only_load_latch false. */
+
+  local_queue_only = session_local_queue_only;
+  if (!local_queue_only && queue_only_load >= 0)
+    {
+    local_queue_only = (load_average = OS_GETLOADAVG()) > queue_only_load;
+    if (local_queue_only)
       {
-      local_queue_only = (load_average = os_getloadavg()) > queue_only_load;
-      if (local_queue_only) queue_only_reason = 3;
+      queue_only_reason = 3;
+      if (queue_only_load_latch) session_local_queue_only = TRUE;
       }
     }
 
index e56f866..d86ea46 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.87 2007/06/22 14:38:58 ph10 Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.88 2007/06/27 11:01:51 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1446,7 +1446,7 @@ while (last > first)
     return var_buffer;
 
     case vtype_load_avg:
-    sprintf(CS var_buffer, "%d", os_getloadavg()); /* load_average */
+    sprintf(CS var_buffer, "%d", OS_GETLOADAVG()); /* load_average */
     return var_buffer;
 
     case vtype_host_lookup:                    /* Lookup if not done so */
index f12e8eb..4a75aed 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.75 2007/06/22 14:38:58 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.76 2007/06/27 11:01:52 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -828,6 +828,7 @@ BOOL    queue_list_requires_admin = TRUE;
 BOOL    queue_only             = FALSE;
 uschar *queue_only_file        = NULL;
 int     queue_only_load        = -1;
+BOOL    queue_only_load_latch  = TRUE;
 BOOL    queue_only_override    = TRUE;
 BOOL    queue_only_policy      = FALSE;
 BOOL    queue_run_first_delivery = FALSE;
@@ -1006,7 +1007,7 @@ script that sets up a copy of Exim for running in the test harness. It seems
 that compilers are now clever, and share constant strings if they can.
 Elsewhere in Exim the string "<" is used. The compiler optimization seems to
 make use of the end of this string in order to save space. So the patching then
-wrecks this. We default this optimization by adding some additional characters
+wrecks this. We defeat this optimization by adding some additional characters
 onto the end of the string. */
 
 uschar *running_status         = US">>>running<<<" "\0EXTRA";
@@ -1163,6 +1164,7 @@ BOOL    system_filter_uid_set  = FALSE;
 BOOL    system_filtering       = FALSE;
 
 BOOL    tcp_nodelay            = TRUE;
+int     test_harness_load_avg  = 0;
 int     thismessage_size_limit = 0;
 int     timeout_frozen_after   = 0;
 BOOL    timestamps_utc         = FALSE;
index f80e88b..920267d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.55 2007/06/22 14:38:58 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.56 2007/06/27 11:01:52 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -527,6 +527,7 @@ extern int     queue_run_pipe;         /* Pipe for synchronizing */
 extern int     queue_interval;         /* Queue running interval */
 extern BOOL    queue_only;             /* TRUE to disable immediate delivery */
 extern int     queue_only_load;        /* Max load before auto-queue */
+extern BOOL    queue_only_load_latch;  /* Latch queue_only_load TRUE */
 extern uschar *queue_only_file;        /* Queue if file exists/not-exists */
 extern BOOL    queue_only_override;    /* Allow override from command line */
 extern BOOL    queue_only_policy;      /* ACL or local_scan wants queue_only */
@@ -735,6 +736,7 @@ extern BOOL    system_filter_uid_set;  /* TRUE if uid set */
 extern BOOL    system_filtering;       /* TRUE when running system filter */
 
 extern BOOL    tcp_nodelay;            /* Controls TCP_NODELAY on daemon */
+extern int     test_harness_load_avg;  /* For use when testing */
 extern int     thismessage_size_limit; /* Limit for this message */
 extern int     timeout_frozen_after;   /* Max time to keep frozen messages */
 extern BOOL    timestamps_utc;         /* Use UTC for all times */
index 00f9f8e..f33ac74 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/macros.h,v 1.34 2007/06/19 14:41:31 ph10 Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.35 2007/06/27 11:01:52 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -15,6 +15,12 @@ a string as a text string. This is sometimes useful for debugging output. */
 #define mac_expanded_string(s) mac_string(s)
 
 
+/* When running in the test harness, the load average is fudged. */
+
+#define OS_GETLOADAVG() \
+  (running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg())
+
+
 /* The address_item structure has a word full of 1-bit flags. These macros
 manipulate them. */
 
index a599ea8..660a5bf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.29 2007/02/06 11:11:40 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.30 2007/06/27 11:01:52 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -302,6 +302,7 @@ static optionlist optionlist_config[] = {
   { "queue_only",               opt_bool,        &queue_only },
   { "queue_only_file",          opt_stringptr,   &queue_only_file },
   { "queue_only_load",          opt_fixed,       &queue_only_load },
+  { "queue_only_load_latch",    opt_bool,        &queue_only_load_latch },
   { "queue_only_override",      opt_bool,        &queue_only_override },
   { "queue_run_in_order",       opt_bool,        &queue_run_in_order },
   { "queue_run_max",            opt_int,         &queue_run_max },
index 637e642..48d493c 100644 (file)
@@ -43,7 +43,7 @@ smtp:
 
 begin retry
 
-* * F,1s,1s
+* * F,2s,1s
 
 
 # End
diff --git a/test/confs/0561 b/test/confs/0561
new file mode 100644 (file)
index 0000000..ecdbf95
--- /dev/null
@@ -0,0 +1,42 @@
+# Exim test configuration 0561
+
+QOLL=true
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+
+queue_only_load = 0.001
+queue_only_load_latch = QOLL
+queue_run_in_order
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+  driver = manualroute
+  route_data = 127.0.0.1
+  self = send
+  transport = t1
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+  driver = smtp
+  port = PORT_D
+
+# End
diff --git a/test/log/0561 b/test/log/0561
new file mode 100644 (file)
index 0000000..6bb3490
--- /dev/null
@@ -0,0 +1,30 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 no immediate delivery: load average 0.01
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmaY-0005vi-00 no immediate delivery: load average 0.01
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 Start queue run: pid=pppp -qq
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmaZ-0005vi-00 no immediate delivery: load average 0.01
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 no immediate delivery: load average 0.01
+1999-03-02 09:44:33 10HmaY-0005vi-00 => usery@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]*
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qq
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 Start queue run: pid=pppp -qq
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 no immediate delivery: load average 0.01
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 no immediate delivery: load average 0.02
+1999-03-02 09:44:33 10HmbA-0005vi-00 => usery@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]*
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qq
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmbD-0005vi-00 no immediate delivery: load average 0.01
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmbE-0005vi-00 no immediate delivery: load average 0.02
diff --git a/test/scripts/0000-Basic/0561 b/test/scripts/0000-Basic/0561
new file mode 100644 (file)
index 0000000..1f55f8d
--- /dev/null
@@ -0,0 +1,43 @@
+# queue_only_load and queue_only_load_latch
+need_ipv4
+#
+exim -bs
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Message 1.
+.
+mail from:<>
+rcpt to:<usery@test.ex>
+data
+Message 2.
+.
+quit
+****
+exim -DSERVER=server -bd -oX PORT_D
+****
+exim -qq
+****
+sleep 1
+killdaemon
+exim -DQOLL=false -DSERVER=server -bd -oX PORT_D
+****
+exim -qq
+****
+sleep 1
+killdaemon
+#
+exim -bs -DQOLL=false
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Message 3.
+.
+mail from:<>
+rcpt to:<usery@test.ex>
+data
+Message 4.
+.
+quit
+****
+no_msglog_check
diff --git a/test/stderr/0561 b/test/stderr/0561
new file mode 100644 (file)
index 0000000..045fadc
--- /dev/null
@@ -0,0 +1,2 @@
+
+******** SERVER ********
diff --git a/test/stdout/0561 b/test/stdout/0561
new file mode 100644 (file)
index 0000000..d37cc1a
--- /dev/null
@@ -0,0 +1,20 @@
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaX-0005vi-00\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaY-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbD-0005vi-00\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbE-0005vi-00\r
+221 myhost.test.ex closing connection\r