Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/doc-docbook/spec.xfpt
Original file line number Diff line number Diff line change
Expand Up @@ -12120,6 +12120,17 @@ contain the trailing slash. If &$config_file$& does not contain a slash,
.vindex "&$config_file$&"
The name of the main configuration file Exim is using.

.vitem &$connection_in_id$&
.vindex "&$connection_in_id$&"
When a incoming connecting in received, this variable contains a unique
id representing epoch+pid+localhost_number. See also &$message_exim_id$&

.vitem &$connection_out_id$&
.vindex "&$connection_out_id$&"
Like &$connection_in_id$&, this variable creates a unique id for the
outgoing connection. This id is preserved when multiple deliveries
use the same connection.

.vitem &$dmarc_domain_policy$& &&&
&$dmarc_status$& &&&
&$dmarc_status_text$& &&&
Expand Down
1 change: 1 addition & 0 deletions src/src/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ if (pid == 0)

store_pool = POOL_PERM;
interface_address = string_copy(interface_address);
connection_in_id = create_connection_id();
store_pool = old_pool;

/* Check for a tls-on-connect port */
Expand Down
8 changes: 8 additions & 0 deletions src/src/deliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ for (address_item * addr2 = addr->next; addr2; addr2 = addr2->next)
addr2->special_action = addr->special_action;
addr2->message = addr->message;
addr2->user_message = addr->user_message;
addr2->connection_out_id = addr->connection_out_id; /* todo: is this needed? */
}
}

Expand Down Expand Up @@ -880,12 +881,14 @@ const uschar * save_domain = deliver_domain;
uschar * save_local = deliver_localpart;
const uschar * save_host = deliver_host;
const uschar * save_address = deliver_host_address;
unsigned long save_connection_out_id = connection_out_id;
const int save_port = deliver_host_port;

router_name = addr->router ? addr->router->name : NULL;
deliver_domain = addr->domain;
deliver_localpart = addr->local_part;
deliver_host = addr->host_used ? addr->host_used->name : NULL;
connection_out_id = addr->connection_out_id;

if (!addr->transport)
{
Expand Down Expand Up @@ -916,6 +919,7 @@ deliver_host = save_host;
deliver_localpart = save_local;
deliver_domain = save_domain;
router_name = transport_name = NULL;
connection_out_id = save_connection_out_id;
}
#endif /*DISABLE_EVENT*/

Expand Down Expand Up @@ -3610,6 +3614,8 @@ while (!done)
ptr += sizeof(addr->delivery_time);
memcpy(&addr->flags, ptr, sizeof(addr->flags));
ptr += sizeof(addr->flags);
memcpy(&addr->connection_out_id, ptr, sizeof(addr->connection_out_id));
ptr += sizeof(addr->connection_out_id);
addr->message = *ptr ? string_copy(ptr) : NULL;
while(*ptr++);
addr->user_message = *ptr ? string_copy(ptr) : NULL;
Expand Down Expand Up @@ -4928,6 +4934,8 @@ all pipes, so I do not see a reason to use non-blocking IO here
ptr += sizeof(addr->delivery_time);
memcpy(ptr, &addr->flags, sizeof(addr->flags));
ptr += sizeof(addr->flags);
memcpy(ptr, &addr->connection_out_id, sizeof(addr->connection_out_id));
ptr += sizeof(addr->connection_out_id);

if (!addr->message) *ptr++ = 0; else
ptr += sprintf(CS ptr, "%.1024s", addr->message) + 1;
Expand Down
5 changes: 4 additions & 1 deletion src/src/exim.c
Original file line number Diff line number Diff line change
Expand Up @@ -2705,7 +2705,7 @@ for (i = 1; i < argc; i++)
union sockaddr_46 interface_sock;
EXIM_SOCKLEN_T size = sizeof(interface_sock);

if (argc != i + 6)
if (argc != 6 && argc != 7)
exim_fail("exim: too many or too few arguments after -MC\n");

if (msg_action_arg >= 0)
Expand All @@ -2721,6 +2721,9 @@ for (i = 1; i < argc; i++)
queue_run_pid = passed_qr_pid;
queue_run_pipe = passed_qr_pipe;

if (argc == 7)
connection_out_id = Uatol(argv[++i]);

if (!mac_ismsgid(argv[i]))
exim_fail("exim: malformed message id %s after -MC option\n",
argv[i]);
Expand Down
7 changes: 6 additions & 1 deletion src/src/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,8 @@ enum vtypes {
vtype_load_avg, /* value not used; result is int from os_getloadavg */
vtype_pspace, /* partition space; value is T/F for spool/log */
vtype_pinodes, /* partition inodes; value is T/F for spool/log */
vtype_cert /* SSL certificate */
vtype_cert, /* SSL certificate */
vtype_connid /* valid: uint64 connection id encoding */
#ifndef DISABLE_DKIM
,vtype_dkim /* Lookup of value in DKIM signature */
#endif
Expand Down Expand Up @@ -517,6 +518,8 @@ static var_entry var_table[] = {
{ "compile_number", vtype_stringptr, &version_cnumber },
{ "config_dir", vtype_stringptr, &config_main_directory },
{ "config_file", vtype_stringptr, &config_main_filename },
{ "connection_in_id", vtype_connid, &connection_in_id },
{ "connection_out_id", vtype_connid, &connection_out_id },
{ "csa_status", vtype_stringptr, &csa_status },
#ifdef EXPERIMENTAL_DCC
{ "dcc_header", vtype_stringptr, &dcc_header },
Expand Down Expand Up @@ -2075,6 +2078,8 @@ switch (vp->type)
return dkim_exim_expand_query((int)(long)val);
#endif

case vtype_connid:
return string_format_connection_id(*(unsigned long *)val);
}

return NULL; /* Unknown variable. Silences static checkers. */
Expand Down
2 changes: 2 additions & 0 deletions src/src/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,8 @@ extern uschar *string_copy_dnsdomain(uschar *);
extern uschar *string_copy_malloc(const uschar *);
extern uschar *string_dequote(const uschar **);
extern uschar *string_format_size(int, uschar *);
extern unsigned long create_connection_id();
extern uschar *string_format_connection_id(unsigned long connection_id);
extern int string_interpret_escape(const uschar **);
extern int string_is_ip_address(const uschar *, int *);
#ifdef SUPPORT_I18N
Expand Down
5 changes: 5 additions & 0 deletions src/src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,9 @@ int av_failed = FALSE; /* boolean but accessed as vtype_int*/
uschar *av_scanner = US"sophie:/var/run/sophie"; /* AV scanner */
#endif

uschar *base62_alpha =
US"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

#if BASE_62 == 62
uschar *base62_chars=
US"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Expand Down Expand Up @@ -723,6 +726,8 @@ uid_t config_uid = CONFIGURE_OWNER;
uid_t config_uid = 0;
#endif

unsigned long connection_in_id = 0;
unsigned long connection_out_id= 0;
int connection_max_messages= -1;
uschar *continue_proxy_cipher = NULL;
uschar *continue_hostname = NULL;
Expand Down
4 changes: 4 additions & 0 deletions src/src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ extern int av_failed; /* TRUE if the AV process failed */
extern uschar *av_scanner; /* AntiVirus scanner to use for the malware condition */
#endif

extern uschar *base62_alpha; /* Table of 62 base-62 characters */
extern uschar *base62_chars; /* Table of base-62 characters */
extern uschar *bi_command; /* Command for -bi option */
extern uschar *big_buffer; /* Used for various temp things */
Expand Down Expand Up @@ -428,6 +429,9 @@ extern uschar *continue_host_address; /* IP address for ditto */
extern int continue_sequence; /* Sequence num for continued delivery */
extern uschar *continue_transport; /* Transport for continued delivery */

extern unsigned long connection_in_id; /* Incoming connection ID */
extern unsigned long connection_out_id;/* Outgoing connection ID */

extern uschar *csa_status; /* Client SMTP Authorization result */

typedef struct {
Expand Down
1 change: 1 addition & 0 deletions src/src/smtp_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ const blob * fastopen_blob = NULL;
#ifndef DISABLE_EVENT
deliver_host_address = host->address;
deliver_host_port = port;
connection_out_id = create_connection_id();
if (event_raise(tb->event_action, US"tcp:connect", NULL)) return -1;
#endif

Expand Down
41 changes: 41 additions & 0 deletions src/src/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,47 @@ else
return buffer;
}

/*************************************************
* Create connection_(in|out)_id uint64 *
*************************************************/

/*
Format is based on message_exim_id:
* 30 bits epoch with msb stripped, making it
impossible to represent dated before 2004
* 22 bits pid
* 12 bits localhost_number & usec

total is uint64
*/

unsigned long
create_connection_id()
{
struct timeval tv;
(void)gettimeofday(&tv, NULL);
exim_wait_tick(&tv, 5000);

return (unsigned long)(tv.tv_sec & 0x3fffffff) << (22 + 12) |
(host_number * 200 + tv.tv_usec / 5000) << 22 | getpid();
}

uschar *
string_format_connection_id(unsigned long connection_id)
{
static uschar yield[12];

uschar *p = yield + sizeof(yield) - 1;
*p = 0;

for (int i=10;i>=0;i--)
{
*(--p) = base62_alpha[connection_id % 62];
connection_id /= 62;
}

return string_copy(yield);
}


#ifndef COMPILE_UTILITY
Expand Down
1 change: 1 addition & 0 deletions src/src/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ typedef struct address_item {
uschar *message; /* error message */
uschar *user_message; /* error message that can be sent over SMTP
or quoted in bounce message */
unsigned long connection_out_id;/* connection_id returned from forked child */
uschar *onetime_parent; /* saved original parent for onetime */
uschar **pipe_expandn; /* numeric expansions for pipe from filter */
uschar *return_filename; /* name of return file */
Expand Down
3 changes: 2 additions & 1 deletion src/src/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -1872,7 +1872,7 @@ void
transport_do_pass_socket(const uschar *transport_name, const uschar *hostname,
const uschar *hostaddress, uschar *id, int socket_fd)
{
int i = 20;
int i = 21;
const uschar **argv;

/* Set up the calling arguments; use the standard function for the basics,
Expand Down Expand Up @@ -1910,6 +1910,7 @@ argv[i++] = US transport_name;
argv[i++] = US hostname;
argv[i++] = US hostaddress;
argv[i++] = string_sprintf("%d", continue_sequence + 1);
argv[i++] = string_sprintf("%ld", connection_out_id);
argv[i++] = id;
argv[i++] = NULL;

Expand Down
1 change: 1 addition & 0 deletions src/src/transports/smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,7 @@ while (count-- > 0)

/* The address was accepted */
addr->host_used = sx->conn_args.host;
addr->connection_out_id = connection_out_id;

DEBUG(D_transport) debug_printf("%s expect rcpt\n", __FUNCTION__);
if (smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
Expand Down