msg to put in each address's message field
rc to put in each address's transport_return field
pass_message if TRUE, set the "pass message" flag in the address
+ host if set, mark addrs as having used this host
If errno_value has the special value ERRNO_CONNECTTIMEOUT, ETIMEDOUT is put in
the errno field, and RTEF_CTOUT is ORed into the more_errno field, to indicate
static void
set_errno(address_item *addrlist, int errno_value, uschar *msg, int rc,
- BOOL pass_message)
+ BOOL pass_message, host_item * host)
{
address_item *addr;
int orvalue = 0;
if (pass_message) setflag(addr, af_pass_message);
}
addr->transport_return = rc;
+ if (host)
+ addr->host_used = host;
}
}
if (*errno_value == ETIMEDOUT)
{
- *message = US string_sprintf("SMTP timeout while connected to %s [%s] "
- "after %s%s", host->name, host->address, pl, smtp_command);
+ *message = US string_sprintf("SMTP timeout after %s%s",
+ pl, smtp_command);
if (transport_count > 0)
*message = US string_sprintf("%s (%d bytes written)", *message,
transport_count);
{
uschar *malfresp = string_printing(buffer);
while (isspace(*malfresp)) malfresp++;
- if (*malfresp == 0)
- *message = string_sprintf("Malformed SMTP reply (an empty line) from "
- "%s [%s] in response to %s%s", host->name, host->address, pl,
- smtp_command);
- else
- *message = string_sprintf("Malformed SMTP reply from %s [%s] in response "
- "to %s%s: %s", host->name, host->address, pl, smtp_command, malfresp);
+ *message = *malfresp == 0
+ ? string_sprintf("Malformed SMTP reply (an empty line) "
+ "in response to %s%s", pl, smtp_command)
+ : string_sprintf("Malformed SMTP reply in response to %s%s: %s",
+ pl, smtp_command, malfresp);
return FALSE;
}
{
uschar *s = string_printing(buffer);
*message = US string_sprintf("SMTP error from remote mail server after %s%s: "
- "host %s [%s]: %s", pl, smtp_command, host->name, host->address, s);
+ "%s", pl, smtp_command, s);
*pass_message = TRUE;
*yield = buffer[0];
return TRUE;
if (*errno_value == 0 || *errno_value == ECONNRESET)
{
*errno_value = ERRNO_SMTPCLOSED;
- *message = US string_sprintf("Remote host %s [%s] closed connection "
- "in response to %s%s", host->name, host->address, pl, smtp_command);
+ *message = US string_sprintf("Remote host closed connection "
+ "in response to %s%s", pl, smtp_command);
}
else *message = US string_sprintf("%s [%s]", host->name, host->address);
static void
write_logs(address_item *addr, host_item *host)
{
-if (addr->message != NULL)
+uschar * message = string_sprintf("H=%s [%s]", host->name, host->address);
+
+if (addr->message)
{
- uschar *message = addr->message;
+ message = string_sprintf("%s: %s", message, addr->message);
if (addr->basic_errno > 0)
message = string_sprintf("%s: %s", message, strerror(addr->basic_errno));
log_write(0, LOG_MAIN, "%s", message);
}
else
{
- uschar *msg =
- ((log_extra_selector & LX_outgoing_port) != 0)?
- string_sprintf("%s [%s]:%d", host->name, host->address,
- (host->port == PORT_NONE)? 25 : host->port)
- :
- string_sprintf("%s [%s]", host->name, host->address);
- log_write(0, LOG_MAIN, "%s %s", msg, strerror(addr->basic_errno));
- deliver_msglog("%s %s %s\n", tod_stamp(tod_log), msg,
- strerror(addr->basic_errno));
+ if (log_extra_selector & LX_outgoing_port)
+ message = string_sprintf("%s:%d", message,
+ host->port == PORT_NONE ? 25 : host->port);
+ log_write(0, LOG_MAIN, "%s %s", message, strerror(addr->basic_errno));
+ deliver_msglog("%s %s %s\n", tod_stamp(tod_log), message,
+ strerror(addr->basic_errno));
}
}
+static void
+msglog_line(host_item * host, uschar * message)
+{
+ deliver_msglog("%s H=%s [%s] %s\n", tod_stamp(tod_log),
+ host->name, host->address, message);
+}
+
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
/*************************************************
* Post-defer action *
*************************************************/
*/
static void
-tpda_deferred(address_item *addr, host_item *host)
+deferred_event_raise(address_item *addr, host_item *host)
{
-uschar * action = addr->transport->tpda_event_action;
+uschar * action = addr->transport->event_action;
uschar * save_domain;
uschar * save_local;
/*XXX would ip & port already be set up? */
deliver_host_address = string_copy(host->address);
-deliver_host_port = (host->port == PORT_NONE)? 25 : host->port;
-tpda_defer_errno = addr->basic_errno;
+deliver_host_port = host->port == PORT_NONE ? 25 : host->port;
+event_defer_errno = addr->basic_errno;
router_name = addr->router->name;
transport_name = addr->transport->name;
deliver_domain = addr->domain;
deliver_localpart = addr->local_part;
-(void) tpda_raise_event(action, US"msg:host:defer",
+(void) event_raise(action, US"msg:host:defer",
addr->message
? addr->basic_errno > 0
? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
}
errno = save_errno;
}
+
+ if (pending_DATA) count--; /* Number of RCPT responses to come */
+ while (count-- > 0) /* Mark any pending addrs with the host used */
+ {
+ while (addr->transport_return != PENDING_DEFER) addr = addr->next;
+ addr->host_used = host;
+ addr = addr->next;
+ }
return -3;
}
}
while (addr->transport_return != PENDING_DEFER) addr = addr->next;
/* The address was accepted */
+ addr->host_used = host;
if (smtp_read_response(inblock, buffer, buffsize, '2', timeout))
{
else if (errno == ETIMEDOUT)
{
int save_errno = errno;
- uschar *message = string_sprintf("SMTP timeout while connected to %s [%s] "
- "after RCPT TO:<%s>", host->name, host->address,
- transport_rcpt_address(addr, include_affixes));
- set_errno(addrlist, save_errno, message, DEFER, FALSE);
+ uschar *message = string_sprintf("SMTP timeout after RCPT TO:<%s>",
+ transport_rcpt_address(addr, include_affixes));
+ set_errno(addrlist, save_errno, message, DEFER, FALSE, NULL);
retry_add_item(addr, addr->address_retry_key, 0);
update_waiting = FALSE;
return -1;
{
addr->message =
string_sprintf("SMTP error from remote mail server after RCPT TO:<%s>: "
- "host %s [%s]: %s", transport_rcpt_address(addr, include_affixes),
- host->name, host->address, string_printing(buffer));
+ "%s", transport_rcpt_address(addr, include_affixes),
+ string_printing(buffer));
setflag(addr, af_pass_message);
- deliver_msglog("%s %s\n", tod_stamp(tod_log), addr->message);
+ msglog_line(host, addr->message);
/* The response was 5xx */
addr->basic_errno = ERRNO_RCPT4XX;
addr->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
- /* Log temporary errors if there are more hosts to be tried. */
+ /* Log temporary errors if there are more hosts to be tried.
+ If not, log this last one in the == line. */
- if (host->next != NULL) log_write(0, LOG_MAIN, "%s", addr->message);
+ if (host->next)
+ log_write(0, LOG_MAIN, "H=%s [%s]: %s", host->name, host->address, addr->message);
/* Do not put this message on the list of those waiting for specific
hosts, as otherwise it is likely to be tried too often. */
/* Internal problem, message in buffer. */
case ERROR:
- set_errno(addrlist, 0, string_copy(buffer), DEFER, FALSE);
+ set_errno(addrlist, 0, string_copy(buffer), DEFER, FALSE, NULL);
return ERROR;
}
{
set_errno(addrlist, ERRNO_AUTHFAIL,
string_sprintf("authentication required but %s", fail_reason), DEFER,
- FALSE);
+ FALSE, NULL);
return DEFER;
}
{
uschar *message = string_sprintf("failed to expand "
"authenticated_sender: %s", expand_string_message);
- set_errno(addrlist, 0, message, DEFER, FALSE);
+ set_errno(addrlist, 0, message, DEFER, FALSE, NULL);
return TRUE;
}
}
#ifndef SUPPORT_TLS
if (smtps)
{
- set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
+ set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE, NULL);
return ERROR;
}
#endif
inblock.sock = outblock.sock =
smtp_connect(host, host_af, port, interface, ob->connect_timeout,
ob->keepalive, ob->dscp
-#ifdef EXPERIMENTAL_TPDA
- , tblock->tpda_event_action
+#ifdef EXPERIMENTAL_EVENT
+ , tblock->event_action
#endif
);
if (inblock.sock < 0)
{
set_errno(addrlist, (errno == ETIMEDOUT)? ERRNO_CONNECTTIMEOUT : errno,
- NULL, DEFER, FALSE);
+ NULL, DEFER, FALSE, NULL);
return DEFER;
}
if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
ob->command_timeout)) goto RESPONSE_FAILED;
-#ifdef EXPERIMENTAL_TPDA
- if (tpda_raise_event(tblock->tpda_event_action, US"smtp:connect", buffer)
- == DEFER)
+#ifdef EXPERIMENTAL_EVENT
+ {
+ uschar * s;
+ lookup_dnssec_authenticated = host->dnssec==DS_YES ? US"yes"
+ : host->dnssec==DS_NO ? US"no" : NULL;
+ s = event_raise(tblock->event_action, US"smtp:connect", buffer);
+ if (s)
{
- uschar *message = US"deferred by smtp:connect event expansion";
- set_errno(addrlist, 0, message, DEFER, FALSE);
+ set_errno(addrlist, 0,
+ string_sprintf("deferred by smtp:connect event expansion: %s", s),
+ DEFER, FALSE, NULL);
yield = DEFER;
goto SEND_QUIT;
}
+ }
#endif
/* Now check if the helo_data expansion went well, and sign off cleanly if
{
uschar *message = string_sprintf("failed to expand helo_data: %s",
expand_string_message);
- set_errno(addrlist, 0, message, DEFER, FALSE);
+ set_errno(addrlist, 0, message, DEFER, FALSE, NULL);
yield = DEFER;
goto SEND_QUIT;
}
/* TLS session is set up */
for (addr = addrlist; addr != NULL; addr = addr->next)
- {
if (addr->transport_return == PENDING_DEFER)
{
addr->cipher = tls_out.cipher;
addr->peerdn = tls_out.peerdn;
addr->ocsp = tls_out.ocsp;
}
- }
}
}
{
uschar *message = string_sprintf("failed to expand helo_data: %s",
expand_string_message);
- set_errno(addrlist, 0, message, DEFER, FALSE);
+ set_errno(addrlist, 0, message, DEFER, FALSE, NULL);
yield = DEFER;
goto SEND_QUIT;
}
)
{
save_errno = ERRNO_TLSREQUIRED;
- message = string_sprintf("a TLS session is required for %s [%s], but %s",
- host->name, host->address,
+ message = string_sprintf("a TLS session is required, but %s",
tls_offered? "an attempt to start TLS failed" :
"the server did not offer TLS support");
goto TLS_FAILED;
if (!rc)
{
set_errno(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
- FALSE);
+ FALSE, NULL);
yield = ERROR;
goto SEND_QUIT;
}
if (badaddr != NULL)
{
set_errno(addrlist, 0, badaddr->message, FAIL,
- testflag(badaddr, af_pass_message));
+ testflag(badaddr, af_pass_message), NULL);
ok = FALSE;
}
}
/* Set up confirmation if needed - applies only to SMTP */
if (
-#ifndef EXPERIMENTAL_TPDA
+#ifndef EXPERIMENTAL_EVENT
(log_extra_selector & LX_smtp_confirmation) != 0 &&
#endif
!lmtp
if (setting_up)
{
if (code == '5')
- {
- set_errno(addrlist, save_errno, message, FAIL, pass_message);
- }
+ set_errno(addrlist, save_errno, message, FAIL, pass_message, host);
else
{
- set_errno(addrlist, save_errno, message, DEFER, pass_message);
+ set_errno(addrlist, save_errno, message, DEFER, pass_message, host);
yield = DEFER;
}
}
{
if (mua_wrapper) code = '5'; /* Force hard failure in wrapper mode */
set_errno(addrlist, save_errno, message, (code == '5')? FAIL : DEFER,
- pass_message);
+ pass_message, host);
/* If there's an errno, the message contains just the identity of
the host. */
if (save_errno > 0)
message = US string_sprintf("%s: %s", message, strerror(save_errno));
if (host->next != NULL) log_write(0, LOG_MAIN, "%s", message);
- deliver_msglog("%s %s\n", tod_stamp(tod_log), message);
+ msglog_line(host, message);
*message_defer = TRUE;
}
}
{
yield = (save_errno == ERRNO_CHHEADER_FAIL ||
save_errno == ERRNO_FILTER_FAIL)? ERROR : DEFER;
- set_errno(addrlist, save_errno, message, DEFER, pass_message);
+ set_errno(addrlist, save_errno, message, DEFER, pass_message, host);
}
}
}
&pass_message);
if (!send_quit)
{
- DEBUG(D_transport) debug_printf("%s\n", msg);
+ DEBUG(D_transport) debug_printf("H=%s [%s] %s\n",
+ host->name, host->address, msg);
}
}
}
/* If RSET failed and there are addresses left, they get deferred. */
- else set_errno(first_addr, errno, msg, DEFER, FALSE);
+ else set_errno(first_addr, errno, msg, DEFER, FALSE, host);
}
}
(void)close(inblock.sock);
-#ifdef EXPERIMENTAL_TPDA
-(void) tpda_raise_event(tblock->tpda_event_action, US"tcp:close", NULL);
+#ifdef EXPERIMENTAL_EVENT
+(void) event_raise(tblock->event_action, US"tcp:close", NULL);
#endif
continue_transport = NULL;
if (dont_deliver)
{
host_item *host2;
- set_errno(addrlist, 0, NULL, OK, FALSE);
+ set_errno(addrlist, 0, NULL, OK, FALSE, NULL);
for (addr = addrlist; addr != NULL; addr = addr->next)
{
addr->host_used = host;
first_addr->basic_errno != ERRNO_TLSFAILURE)
write_logs(first_addr, host);
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
if (rc == DEFER)
- tpda_deferred(first_addr, host);
+ deferred_event_raise(first_addr, host);
#endif
/* If STARTTLS was accepted, but there was a failure in setting up the
expanded_hosts != NULL, &message_defer, TRUE);
if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL)
write_logs(first_addr, host);
-# ifdef EXPERIMENTAL_TPDA
+# ifdef EXPERIMENTAL_EVENT
if (rc == DEFER)
- tpda_deferred(first_addr, host);
+ deferred_event_raise(first_addr, host);
# endif
}
#endif /*SUPPORT_TLS*/