diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2021-04-10 19:36:17 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2021-04-10 19:36:17 +0100 |
commit | cf39dad3d551222a3e1f681995c287eb53e2596f (patch) | |
tree | eca9e4752d68202475f4345f0749e7a5de1f235b /src | |
parent | 2081aac24b67f3f3f34389aadc06354abcad0cad (diff) |
Logging: better tracking of continued-connection use
Diffstat (limited to 'src')
-rw-r--r-- | src/src/deliver.c | 28 | ||||
-rw-r--r-- | src/src/structs.h | 2 | ||||
-rw-r--r-- | src/src/transport.c | 21 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 21 |
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 |