summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2021-04-10 19:36:17 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2021-04-10 19:36:17 +0100
commitcf39dad3d551222a3e1f681995c287eb53e2596f (patch)
treeeca9e4752d68202475f4345f0749e7a5de1f235b /src
parent2081aac24b67f3f3f34389aadc06354abcad0cad (diff)
Logging: better tracking of continued-connection use
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c28
-rw-r--r--src/src/structs.h2
-rw-r--r--src/src/transport.c21
-rw-r--r--src/src/transports/smtp.c21
4 files changed, 51 insertions, 21 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index ec39cf15e..ef6eb22e2 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -1580,6 +1580,12 @@ if (addr->return_file >= 0 && addr->return_filename)
(void)close(addr->return_file);
}
+/* Check if the transport notifed continue-conn status explicitly, and
+update our knowlege. */
+
+if (testflag(addr, af_new_conn)) continue_sequence = 1;
+else if (testflag(addr, af_cont_conn)) continue_sequence++;
+
/* The success case happens only after delivery by a transport. */
if (result == OK)
@@ -3571,7 +3577,13 @@ while (!done)
switch (*subid)
{
- #ifdef SUPPORT_SOCKS
+ case 3: /* explicit notification of continued-connection (non)use;
+ overrides caller's knowlege. */
+ if (*ptr & BIT(1)) setflag(addr, af_new_conn);
+ else if (*ptr & BIT(2)) setflag(addr, af_cont_conn);
+ break;
+
+#ifdef SUPPORT_SOCKS
case '2': /* proxy information; must arrive before A0 and applies to that addr XXX oops*/
proxy_session = TRUE; /*XXX should this be cleared somewhere? */
if (*ptr == 0)
@@ -3584,9 +3596,9 @@ while (!done)
ptr += sizeof(proxy_local_port);
}
break;
- #endif
+#endif
- #ifdef EXPERIMENTAL_DSN_INFO
+#ifdef EXPERIMENTAL_DSN_INFO
case '1': /* must arrive before A0, and applies to that addr */
/* Two strings: smtp_greeting and helo_response */
addr->smtp_greeting = string_copy(ptr);
@@ -3594,7 +3606,7 @@ while (!done)
addr->helo_response = string_copy(ptr);
while(*ptr++);
break;
- #endif
+#endif
case '0':
DEBUG(D_deliver) debug_printf("A0 %s tret %d\n", addr->address, *ptr);
@@ -4885,6 +4897,14 @@ all pipes, so I do not see a reason to use non-blocking IO here
rmt_dlv_checked_write(fd, 'R', '0', big_buffer, ptr - big_buffer);
}
+ if (testflag(addr, af_new_conn) || testflag(addr, af_cont_conn))
+ {
+ DEBUG(D_deliver) debug_printf("%scontinued-connection\n",
+ testflag(addr, af_new_conn) ? "non-" : "");
+ big_buffer[0] = testflag(addr, af_new_conn) ? BIT(1) : BIT(2);
+ rmt_dlv_checked_write(fd, 'A', '3', big_buffer, 1);
+ }
+
#ifdef SUPPORT_SOCKS
if (LOGGING(proxy) && proxy_session)
{
diff --git a/src/src/structs.h b/src/src/structs.h
index f88d126dc..9bfc8826b 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -626,6 +626,8 @@ typedef struct address_item {
BOOL af_verify_routed:1; /* for cached sender verify: routed OK */
BOOL af_verify_callout:1; /* for cached sender verify: callout was specified */
BOOL af_include_affixes:1; /* delivered with affixes in RCPT */
+ BOOL af_new_conn:1; /* delivered on an fresh TCP conn */
+ BOOL af_cont_conn:1; /* delivered (with new MAIL cmd) on an existing TCP conn */
BOOL af_cert_verified:1; /* delivered with verified TLS cert */
BOOL af_pass_message:1; /* pass message in bounces */
BOOL af_bad_reply:1; /* filter could not generate autoreply */
diff --git a/src/src/transport.c b/src/src/transport.c
index 39b8c411a..49a84ccc4 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -2247,12 +2247,12 @@ if (expand_arguments)
}
/* If we are not just able to replace the slot that contained
- * $address_pipe (address_pipe_argcount == 1)
- * We have to move the existing argv by address_pipe_argcount - 1
- * Visually if address_pipe_argcount == 2:
- * [argv 0][argv 1][argv 2($address_pipe)][argv 3][0]
- * [argv 0][argv 1][ap_arg0][ap_arg1][old argv 3][0]
- */
+ $address_pipe (address_pipe_argcount == 1)
+ We have to move the existing argv by address_pipe_argcount - 1
+ Visually if address_pipe_argcount == 2:
+ [argv 0][argv 1][argv 2($address_pipe)][argv 3][0]
+ [argv 0][argv 1][ap_arg0][ap_arg1][old argv 3][0] */
+
if (address_pipe_argcount > 1)
memmove(
/* current position + additional args */
@@ -2264,15 +2264,12 @@ if (expand_arguments)
);
/* Now we fill in the slots we just moved argv out of
- * [argv 0][argv 1][argv 2=pipeargv[0]][argv 3=pipeargv[1]][old argv 3][0]
- */
+ [argv 0][argv 1][argv 2=pipeargv[0]][argv 3=pipeargv[1]][old argv 3][0] */
+
for (int address_pipe_i = 0;
address_pipe_argv[address_pipe_i] != US 0;
- address_pipe_i++)
- {
+ address_pipe_i++, argcount++)
argv[i++] = address_pipe_argv[address_pipe_i];
- argcount++;
- }
/* Subtract one since we replace $address_pipe */
argcount--;
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index c6099f960..2a2928c46 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -1827,15 +1827,13 @@ return OK;
-
-
/*************************************************
* Make connection for given message *
*************************************************/
/*
Arguments:
- ctx connection context
+ sx connection context
suppress_tls if TRUE, don't attempt a TLS connection - this is set for
a second attempt after TLS initialization fails
@@ -2027,6 +2025,11 @@ if (!continue_hostname)
if (sx->verify)
HDEBUG(D_verify) debug_printf("interface=%s port=%d\n", sx->conn_args.interface, sx->port);
+ /* Arrange to report to calling process this is a new connection */
+
+ clearflag(sx->first_addr, af_cont_conn);
+ setflag(sx->first_addr, af_new_conn);
+
/* Get the actual port the connection will use, into sx->conn_args.host */
smtp_port_for_connect(sx->conn_args.host, sx->port);
@@ -3223,7 +3226,7 @@ that max_rcpt will be large, so all addresses will be done at once.
For verify we flush the pipeline after any (the only) rcpt address. */
for (addr = sx->first_addr, address_count = 0, pipe_limit = 100;
- addr && address_count < sx->max_rcpt;
+ addr && address_count < sx->max_rcpt;
addr = addr->next) if (addr->transport_return == PENDING_DEFER)
{
int cmds_sent;
@@ -4385,7 +4388,9 @@ if (sx->completed_addr && sx->ok && sx->send_quit)
if (sx->first_addr) /* More addresses still to be sent */
{ /* for this message */
- continue_sequence++; /* Causes * in logging */
+ continue_sequence++; /* for consistency */
+ clearflag(sx->first_addr, af_new_conn);
+ setflag(sx->first_addr, af_cont_conn); /* Causes * in logging */
pipelining_active = sx->pipelining_used; /* was cleared at DATA */
goto SEND_MESSAGE;
}
@@ -4580,6 +4585,9 @@ if (sx->send_quit || tcw_done && !tcw)
}
HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n");
(void)close(sx->cctx.sock);
+sx->cctx.sock = -1;
+continue_transport = NULL;
+continue_hostname = NULL;
#ifndef DISABLE_EVENT
(void) event_raise(tblock->event_action, US"tcp:close", NULL);
@@ -4599,9 +4607,12 @@ if (dane_held)
to get the domain string for SNI */
sx->first_addr = a;
+ clearflag(a, af_cont_conn);
+ setflag(a, af_new_conn); /* clear * from logging */
DEBUG(D_transport) debug_printf("DANE: go-around for %s\n", a->domain);
}
}
+ continue_sequence = 1; /* for consistency */
goto DANE_DOMAINS;
}
#endif