.vitem &%-odqs%&
.oindex "&%-odqs%&"
.cindex "SMTP" "delaying delivery"
+.cindex "first pass routing"
This option is a hybrid between &%-odb%&/&%-odi%& and &%-odq%&.
However, like &%-odb%& and &%-odi%&, this option has no effect if
&%queue_only_override%& is false and one of the queueing options in the
.cindex "queue" "double scanning"
.cindex "queue" "routing"
.cindex "routing" "whole queue before delivery"
+.cindex "first pass routing"
An option starting with &%-qq%& requests a two-stage queue run. In the first
stage, the queue is scanned as if the &%queue_smtp_domains%& option matched
every domain. Addresses are routed, local deliveries happen, but no remote
.option queue_smtp_domains main "domain list&!!" unset
.cindex "queueing incoming messages"
.cindex "message" "queueing remote deliveries"
+.cindex "first pass routing"
When this option is set, a delivery process is started whenever a message is
received, routing is performed, and local deliveries take place.
However, if any SMTP deliveries are required for domains that match
controlled by &%acl_smtp_connect%& or &%acl_smtp_helo%&. See also
&%pipelining_advertise_hosts%&.
+.new
+.vitem &*control&~=&~queue/*&<&'options'&>*
.vitem &*control&~=&~queue_only*&
+.oindex "&%queue%&"
.oindex "&%queue_only%&"
.cindex "queueing incoming messages"
+.cindex queueing "forcing in ACL"
+.cindex "first pass routing"
This control is permitted only for the MAIL, RCPT, DATA, and non-SMTP ACLs, in
other words, only when a message is being received. If the message is accepted,
it is placed on Exim's queue and left there for delivery by a subsequent queue
-runner. No immediate delivery process is started. In other words, it has the
-effect as the &%queue_only%& global option. However, the control applies only
-to the current message, not to any subsequent ones that may be received in the
-same SMTP connection.
+runner.
+If used with no options set,
+no immediate delivery process is started. In other words, it has the
+effect as the &%queue_only%& global option or &'-odq'& command-line option.
+
+If the &'first_pass_route'& option is given then
+the behaviour is like the command-line &'-oqds'& option;
+a delivery process is started which stops short of making
+any SMTP delivery. The benefit is that the hints database will be updated for
+the message being waiting for a specific host, and a later queue run will be
+able to send all such messages on a single connection.
+
+The control only applies to the current message, not to any subsequent ones that
+ may be received in the same SMTP connection.
+.wen
.vitem &*control&~=&~submission/*&<&'options'&>
.cindex "message" "submission"
.cindex "SMTP" "passed connection"
.cindex "SMTP" "multiple deliveries"
.cindex "multiple SMTP deliveries"
+.cindex "first pass routing"
Mail waiting to be sent from an intermittently connected host will probably
not have been routed, because without a connection DNS lookups are not
possible. This means that if a normal queue run is done at connection time,
8. As an exerimental feature, the dovecot authenticatino driver supports inet
sockets. Previously it was unix-domain sockets only.
+ 9. The ACL control "queue_only" can also be spelled "queue", and now takes an
+ option "first_pass_route" to do the same as a "-odqs" on the command line.
+
Version 4.93
------------
CONTROL_NO_MULTILINE,
CONTROL_NO_PIPELINING,
+ CONTROL_QUEUE,
CONTROL_QUEUE_ONLY,
CONTROL_SUBMISSION,
CONTROL_SUPPRESS_LOCAL_FIXUPS,
ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START
},
+[CONTROL_QUEUE] =
+ { US"queue", TRUE,
+ (unsigned)
+ ~(ACL_BIT_MAIL | ACL_BIT_RCPT |
+ ACL_BIT_PREDATA | ACL_BIT_DATA |
+ // ACL_BIT_PRDR| /* Not allow one user to freeze for all */
+ ACL_BIT_NOTSMTP | ACL_BIT_MIME)
+ },
[CONTROL_QUEUE_ONLY] =
- { US"queue_only", FALSE,
+ { US"queue_only", TRUE,
(unsigned)
~(ACL_BIT_MAIL | ACL_BIT_RCPT |
ACL_BIT_PREDATA | ACL_BIT_DATA |
cancel_cutthrough_connection(TRUE, US"item frozen");
break;
+ case CONTROL_QUEUE:
case CONTROL_QUEUE_ONLY:
f.queue_only_policy = TRUE;
cancel_cutthrough_connection(TRUE, US"queueing forced");
+ while (*p == '/')
+ if (Ustrncmp(p, "/first_pass_route", 17) == 0)
+ {
+ p += 17;
+ f.queue_smtp = TRUE;
+ }
break;
case CONTROL_SUBMISSION:
If we are not root, we have to re-exec exim unless deliveries are being
done unprivileged. */
- else if (!f.queue_only_policy && !f.deliver_freeze)
+ else if ( (!f.queue_only_policy || f.queue_smtp)
+ && !f.deliver_freeze)
{
pid_t dpid;
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK)
)
{
+ DEBUG(D_transport) debug_printf("first-pass routing only\n");
expired = FALSE;
for (address_item * addr = addrlist; addr; addr = addr->next)
if (addr->transport_return == DEFER)
- addr->message = US"domain matches queue_smtp_domains, or -odqs set";
+ addr->message = US"first-pass only routing due to -odqs, "
+ "queue_smtp_domains or control=queue";
continue; /* With next host */
}
--- /dev/null
+# Exim test configuration 0599
+# control = queue/first_pass_route
+
+.include DIR/aux-var/std_conf_prefix
+
+
+# ----- Main settings -----
+
+domainlist local_domains = @
+
+acl_smtp_rcpt = check_rcpt
+
+trusted_users = CALLER
+queue_run_in_order
+
+
+# ----- ACL -----
+
+begin acl
+
+check_rcpt:
+ accept senders = HOSTIPV4
+
+ accept local_parts = ^queue_only.*
+ control = queue_only
+
+ accept local_parts = ^first_pass_route.*
+ control = queue/first_pass_route
+
+# ----- Routers -----
+
+begin routers
+
+discard_remote_source:
+ driver = redirect
+ condition = ${if !eq {$sender_host_address}{127.0.0.1}}
+ data = :blackhole:
+
+outbound:
+ driver = accept
+ transport = smtp
+
+
+# ----- Transports -----
+
+begin transports
+
+smtp:
+ driver = smtp
+ hosts = HOSTIPV4
+ port = PORT_D
+ allow_localhost
+
+# End
1999-03-02 09:44:33 10HmbB-0005vi-00 *> xxx@ten-1.test.ex R=lookuphost T=smtp H=ten-1.test.ex [V4NET.0.0.1] C="delivery bypassed by -N option"
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbC-0005vi-00 == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+1999-03-02 09:44:33 10HmbC-0005vi-00 == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
1999-03-02 09:44:33 Start queue run: pid=pppp
1999-03-02 09:44:33 10HmbC-0005vi-00 *> xxx@ten-2.test.ex R=lookuphost T=smtp H=ten-2.test.ex [V4NET.0.0.2] C="delivery bypassed by -N option"
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qq
1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbF-0005vi-00 == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+1999-03-02 09:44:33 10HmbF-0005vi-00 == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
1999-03-02 09:44:33 10HmbF-0005vi-00 *> xxx@ten-2.test.ex R=lookuphost T=smtp H=ten-2.test.ex [V4NET.0.0.2] C="delivery bypassed by -N option"
1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1.ex R=smarthost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain2.ex R=smarthost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1.ex R=smarthost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain2.ex R=smarthost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
--- /dev/null
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 => queue_only_1@test.ex R=outbound T=smtp H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => queue_only_2@test.ex R=outbound T=smtp H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <queue_only_1@test.ex> R=discard_remote_source
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <queue_only_2@test.ex> R=discard_remote_source
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmbB-0005vi-00 => first_pass_route_1@test.ex R=outbound T=smtp H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbD-0005vi-00 => first_pass_route_2@test.ex R=outbound T=smtp H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]* C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 End queue run: pid=pppp
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex H=(me) [127.0.0.1] P=smtp S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=(me) [127.0.0.1] P=smtp S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex H=the.local.host.name [ip4.ip4.ip4.ip4] P=esmtp S=sss
+1999-03-02 09:44:33 10HmaY-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex H=the.local.host.name [ip4.ip4.ip4.ip4] P=esmtp S=sss
+1999-03-02 09:44:33 10HmbA-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex H=(me) [127.0.0.1] P=smtp S=sss
+1999-03-02 09:44:33 10HmbB-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@test.ex H=(me) [127.0.0.1] P=smtp S=sss
+1999-03-02 09:44:33 10HmbD-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbB-0005vi-00 == first_pass_route_1@test.ex R=outbound T=smtp defer (0): SMTP delivery explicitly queued
+1999-03-02 09:44:33 10HmbD-0005vi-00 == first_pass_route_2@test.ex R=outbound T=smtp defer (0): SMTP delivery explicitly queued
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@test.ex H=the.local.host.name [ip4.ip4.ip4.ip4] P=esmtp S=sss
+1999-03-02 09:44:33 10HmbC-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <first_pass_route_1@test.ex> R=discard_remote_source
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@test.ex H=the.local.host.name [ip4.ip4.ip4.ip4] P=esmtp S=sss
+1999-03-02 09:44:33 10HmbE-0005vi-00 no immediate delivery: queued by ACL
+1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <first_pass_route_2@test.ex> R=discard_remote_source
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
--- /dev/null
+# control = queue/first_pass_route
+#
+exim -bd -DSERVER=server -oX PORT_D
+****
+#
+# First, control=queue_only - we expact the queue run to make separate connections
+client 127.0.0.1 PORT_D
+??? 220
+HELO me
+??? 250
+MAIL FROM:<CALLER@test.ex>
+??? 250
+RCPT TO:<queue_only_1@test.ex>
+??? 250
+DATA
+??? 354
+Subject: 1
+.
+??? 250
+RSET
+??? 250
+MAIL FROM:<CALLER@test.ex>
+??? 250
+RCPT TO:<queue_only_2@test.ex>
+??? 250
+DATA
+??? 354
+Subject: 2
+.
+??? 250
+QUIT
+****
+exim -q
+****
+exim -q
+****
+#
+# Second, control=queue/first_pass_route - we expect the queue run to make only one
+# connection, and put both messages over it
+client 127.0.0.1 PORT_D
+??? 220
+HELO me
+??? 250
+MAIL FROM:<CALLER@test.ex>
+??? 250
+RCPT TO:<first_pass_route_1@test.ex>
+??? 250
+DATA
+??? 354
+Subject: 1
+.
+??? 250
+RSET
+??? 250
+MAIL FROM:<CALLER@test.ex>
+??? 250
+RCPT TO:<first_pass_route_2@test.ex>
+??? 250
+DATA
+??? 354
+Subject: 2
+.
+??? 250
+QUIT
+****
+# give time for the background routing in the exim daemon to complete
+sleep 1
+# then run the queue
+exim -q
+****
+exim -q
+****
+#
+#
+killdaemon
+no_msglog_check
<= CALLER@myhost.ex U=CALLER P=local S=sss
delivering 10HmbC-0005vi-00
LOG: MAIN
- == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+ == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
LOG: queue_run MAIN
Start queue run: pid=pppp
delivering 10HmbC-0005vi-00 (queue run pid ppppp)
<= CALLER@myhost.ex U=CALLER P=local S=sss
delivering 10HmbF-0005vi-00
LOG: MAIN
- == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+ == xxx@ten-2.test.ex R=lookuphost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
delivering 10HmbF-0005vi-00
LOG: MAIN
*> xxx@ten-2.test.ex R=lookuphost T=smtp H=ten-2.test.ex [V4NET.0.0.2] C="delivery bypassed by -N option"
╰─────result: domain1.ex
╰──(tainted)
LOG: MAIN
- == userx@domain1.ex R=smarthost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+ == userx@domain1.ex R=smarthost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
LOG: MAIN
- == userx@domain2.ex R=smarthost T=smtp defer (-1): domain matches queue_smtp_domains, or -odqs set
+ == userx@domain2.ex R=smarthost T=smtp defer (-1): first-pass only routing due to -odqs, queue_smtp_domains or control=queue
╭considering: ${if or {{ !eq{$h_list-id:$h_list-post:$h_list-subscribe:}{} }{ match{$h_precedence:}{(?i)bulk|list|junk} }{ match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }} {no}{yes}}
╭considering: $h_list-id:$h_list-post:$h_list-subscribe:}{} }{ match{$h_precedence:}{(?i)bulk|list|junk} }{ match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }} {no}{yes}}
├──expanding: $h_list-id:$h_list-post:$h_list-subscribe:
--- /dev/null
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> HELO me
+??? 250
+<<< 250 the.local.host.name Hello me [127.0.0.1]
+>>> MAIL FROM:<CALLER@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<queue_only_1@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: 1
+>>> .
+??? 250
+<<< 250 OK id=10HmaX-0005vi-00
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<CALLER@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<queue_only_2@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: 2
+>>> .
+??? 250
+<<< 250 OK id=10HmaZ-0005vi-00
+>>> QUIT
+End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> HELO me
+??? 250
+<<< 250 the.local.host.name Hello me [127.0.0.1]
+>>> MAIL FROM:<CALLER@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<first_pass_route_1@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: 1
+>>> .
+??? 250
+<<< 250 OK id=10HmbB-0005vi-00
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<CALLER@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<first_pass_route_2@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: 2
+>>> .
+??? 250
+<<< 250 OK id=10HmbD-0005vi-00
+>>> QUIT
+End of script