Add systemd units (examples)
[exim.git] / src / src / structs.h
index f95c63ac0aeb0504ca0f3ff731e6a5e8c393d58c..9d2a76ef2985ea3d684ca271fbf40ee6d119a56f 100644 (file)
@@ -1,11 +1,11 @@
-/* $Cambridge: exim/src/src/structs.h,v 1.7 2005/09/12 15:09:55 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2005 */
+/* Copyright (c) The Exim Maintainers 2020 - 2022 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 
 /* Definitions of various structures. In addition, those that are visible for
@@ -27,20 +27,29 @@ struct smtp_outblock;
 struct transport_info;
 struct router_info;
 
+/* Growable-string */
+typedef struct gstring {
+  int  size;           /* Current capacity of string memory */
+  int  ptr;            /* Offset at which to append further chars */
+  uschar * s;          /* The string memory */
+} gstring;
+
 /* Structure for remembering macros for the configuration file */
 
 typedef struct macro_item {
-  struct  macro_item *next;
-  BOOL    command_line;
-  uschar *replacement;
-  uschar  name[1];
+  struct  macro_item * next;
+  BOOL         command_line;
+  unsigned     namelen;
+  unsigned     replen;
+  const uschar * name;
+  const uschar * replacement;
 } macro_item;
 
 /* Structure for bit tables for debugging and logging */
 
 typedef struct bit_table {
   uschar *name;
-  unsigned int bit;
+  int bit;
 } bit_table;
 
 /* Block for holding a uid and gid, possibly unset, and an initgroups flag. */
@@ -53,21 +62,37 @@ typedef struct ugid_block {
   BOOL    initgroups;
 } ugid_block;
 
+typedef enum { CHUNKING_NOT_OFFERED = -1,
+               CHUNKING_OFFERED,
+               CHUNKING_ACTIVE,
+               CHUNKING_LAST} chunking_state_t;
+
+typedef enum { TFO_NOT_USED = 0,
+               TFO_ATTEMPTED_NODATA,
+               TFO_ATTEMPTED_DATA,
+               TFO_USED_NODATA,
+               TFO_USED_DATA } tfo_state_t;
+
 /* Structure for holding information about a host for use mainly by routers,
 but also used when checking lists of hosts and when transporting. Looking up
 host addresses is done using this structure. */
 
+typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;
+
 typedef struct host_item {
   struct host_item *next;
-  uschar *name;                   /* Host name */
-  uschar *address;                /* IP address in text form */
-  int     port;                   /* port value in host order (if SRV lookup) */
-  int     mx;                     /* MX value if found via MX records */
-  int     sort_key;               /* MX*1000 plus random "fraction" */
-  int     status;                 /* Usable, unusable, or unknown */
-  int     why;                    /* Why host is unusable */
-  int     last_try;               /* Time of last try if known */
-  BOOL    update_waiting;         /* Turned off if wait db not to be updated */
+  const uschar *name;          /* Host name */
+#ifndef DISABLE_TLS
+  const uschar *certname;      /* Name used for certificate checks */
+#endif
+  const uschar *address;       /* IP address in text form */
+  int     port;                        /* port value in host order (if SRV lookup) */
+  int     mx;                  /* MX value if found via MX records */
+  int     sort_key;            /* MX*1000 plus random "fraction" */
+  int     status;              /* Usable, unusable, or unknown */
+  int     why;                 /* Why host is unusable */
+  int     last_try;            /* Time of last try if known */
+  dnssec_status_t dnssec;
 } host_item;
 
 /* Chain of rewrite rules, read from the rewrite config, or parsed from the
@@ -89,6 +114,7 @@ typedef struct transport_feedback {
   uschar *port;
   uschar *protocol;
   uschar *hosts;
+  uschar *helo_data;
   BOOL   hosts_override;
   BOOL   hosts_randomize;
   BOOL   gethostbyname;
@@ -108,11 +134,15 @@ typedef struct driver_instance {
   uschar *name;                   /* Instance name */
   struct driver_info *info;       /* Points to info for this driver */
   void   *options_block;          /* Pointer to private options */
+
   uschar *driver_name;            /* All start with this generic option */
+  const uschar *srcfile;         /* and config source info for errors */
+  int    srcline;
 } driver_instance;
 
 typedef struct driver_info {
   uschar *driver_name;            /* Name of driver */
+
   optionlist *options;            /* Table of private options names */
   int    *options_count;          /* -> Number of entries in table */
   void   *options_block;          /* Points to default private block */
@@ -134,10 +164,15 @@ typedef struct transport_instance {
   struct transport_info *info;    /* Info for this driver */
   void *options_block;            /* Pointer to private options */
   uschar *driver_name;            /* Must be first */
+  const uschar *srcfile;
+  int    srcline;
+
   int   (*setup)(                 /* Setup entry point */
     struct transport_instance *,
     struct address_item *,
     struct transport_feedback *,  /* For passing back config data */
+    uid_t,                        /* The uid that will be used */
+    gid_t,                        /* The gid that will be used */
     uschar **);                   /* For an error message */
                                   /**************************************/
   int     batch_max;              /* )                                  */
@@ -145,9 +180,10 @@ typedef struct transport_instance {
   uschar *home_dir;               /* ) Used only for local transports   */
   uschar *current_dir;            /* )                                  */
                                   /**************************************/
+  uschar *expand_multi_domain;    /* )                                  */
   BOOL    multi_domain;           /* )                                  */
   BOOL    overrides_hosts;        /* ) Used only for remote transports  */
-  int     max_addresses;          /* )                                  */
+  uschar *max_addresses;          /* )                                  */
   int     connection_max_messages;/* )                                  */
                                   /**************************************/
   BOOL    deliver_as_creator;     /* Used only by pipe at present */
@@ -167,6 +203,7 @@ typedef struct transport_instance {
   uschar *remove_headers;         /* Remove these headers */
   uschar *return_path;            /* Overriding (rewriting) return path */
   uschar *debug_string;           /* Debugging output */
+  uschar *max_parallel;           /* Number of concurrent instances */
   uschar *message_size_limit;     /* Biggest message this transport handles */
   uschar *headers_rewrite;        /* Rules for rewriting headers */
   rewrite_rule *rewrite_rules;    /* Parsed rewriting rules */
@@ -184,6 +221,9 @@ typedef struct transport_instance {
   BOOL    log_fail_output;
   BOOL    log_defer_output;
   BOOL    retry_use_local_part;   /* Defaults true for local, false for remote */
+#ifndef DISABLE_EVENT
+  uschar  *event_action;          /* String to expand on notable events */
+#endif
 } transport_instance;
 
 
@@ -210,6 +250,38 @@ typedef struct transport_info {
 } transport_info;
 
 
+/* smtp transport datachunk callback */
+
+#define tc_reap_prev   BIT(0)  /* Flags: reap previous SMTP cmd responses */
+#define tc_chunk_last  BIT(1)  /* annotate chunk SMTP cmd as LAST */
+
+struct transport_context;
+typedef int (*tpt_chunk_cmd_cb)(struct transport_context *, unsigned, unsigned);
+
+/* Structure for information about a delivery-in-progress */
+
+typedef struct transport_context {
+  union {                      /* discriminated by option topt_output_string */
+    int                          fd;   /* file descriptor to write message to */
+    gstring *            msg;  /* allocated string with written message */
+  } u;
+  transport_instance   * tblock;               /* transport */
+  struct address_item  * addr;
+  uschar               * check_string;         /* string replacement */
+  uschar               * escape_string;
+  int                    options;              /* output processing topt_* */
+
+  /* items below only used with option topt_use_bdat */
+  tpt_chunk_cmd_cb       chunk_cb;             /* per-datachunk callback */
+  void                 * smtp_context;
+} transport_ctx;
+
+
+
+typedef struct {
+  uschar *request;
+  uschar *require;
+} dnssec_domains;
 
 /* Structure for holding information about the configured routers. */
 
@@ -219,6 +291,8 @@ typedef struct router_instance {
   struct router_info *info;
   void   *options_block;          /* Pointer to private options */
   uschar *driver_name;            /* Must be first */
+  const uschar *srcfile;
+  int    srcline;
 
   uschar *address_data;           /* Arbitrary data */
 #ifdef EXPERIMENTAL_BRIGHTMAIL
@@ -273,12 +347,14 @@ typedef struct router_instance {
   BOOL    retry_use_local_part;   /* Just what it says */
   BOOL    same_domain_copy_routing; /* TRUE => copy routing for same domain */
   BOOL    self_rewrite;           /* TRUE to rewrite headers if making local */
+  uschar *set;                   /* Variable = value to set; list */
   BOOL    suffix_optional;        /* As it says */
   BOOL    verify_only;            /* Skip this router if not verifying */
   BOOL    verify_recipient;       /* Use this router when verifying a recipient*/
   BOOL    verify_sender;          /* Use this router when verifying a sender */
   BOOL    uid_set;                /* Flag to indicate uid is set */
   BOOL    unseen;                 /* If TRUE carry on, even after success */
+  BOOL    dsn_lasthop;            /* If TRUE, this router is a DSN endpoint */
 
   int     self_code;              /* Encoded version of "self" */
   uid_t   uid;                    /* Fixed uid value */
@@ -288,6 +364,8 @@ typedef struct router_instance {
   transport_instance *transport;  /* Transport block (when found) */
   struct router_instance *pass_router; /* Actual router for passed address */
   struct router_instance *redirect_router; /* Actual router for generated address */
+
+  dnssec_domains dnssec;
 } router_instance;
 
 
@@ -320,34 +398,7 @@ typedef struct router_info {
 
 /* Structure for holding information about a lookup type. */
 
-typedef struct lookup_info {
-  uschar *name;                   /* e.g. "lsearch" */
-  int type;                       /* query/singlekey/abs-file */
-  void *(*open)(                  /* open function */
-    uschar *,                     /* file name for those that have one */
-    uschar **);                   /* for error message */
-  BOOL (*check)(                  /* file checking function */
-    void *,                       /* handle */
-    uschar *,                     /* file name */
-    int,                          /* modemask for file checking */
-    uid_t *,                      /* owners for file checking */
-    gid_t *,                      /* owngroups for file checking */
-    uschar **);                   /* for error messages */
-  int (*find)(                    /* find function */
-    void *,                       /* handle */
-    uschar *,                     /* file name or NULL */
-    uschar *,                     /* key or query */
-    int,                          /* length of key or query */
-    uschar **,                    /* for returning answer */
-    uschar **,                    /* for error message */
-    BOOL *);                      /* to request cache cleanup */
-  void (*close)(                  /* close function */
-    void *);                      /* handle */
-  void (*tidy)(void);             /* tidy function */
-  uschar *(*quote)(               /* quoting function */
-    uschar *,                     /* string to quote */
-    uschar *);                    /* additional data from quote name */
-} lookup_info;
+#include "lookupapi.h"
 
 
 /* Structure for holding information about the configured authentication
@@ -359,11 +410,17 @@ typedef struct auth_instance {
   struct auth_info *info;         /* Pointer to driver info block */
   void   *options_block;          /* Pointer to private options */
   uschar *driver_name;            /* Must be first */
+  const uschar *srcfile;
+  int    srcline;
+
   uschar *advertise_condition;    /* Are we going to advertise this?*/
+  uschar *client_condition;       /* Should the client try this? */
   uschar *public_name;            /* Advertised name */
-  uschar *set_id;                 /* String to set as authenticated id */
+  uschar *set_id;                 /* String to set when server as authenticated id */
+  uschar *set_client_id;          /* String to set when client as client_authenticated id */
   uschar *mail_auth_condition;    /* Condition for AUTH on MAIL command */
   uschar *server_debug_string;    /* Debugging output */
+  uschar *server_condition;       /* Authorization condition */
   BOOL    client;                 /* TRUE if client option(s) set */
   BOOL    server;                 /* TRUE if server options(s) set */
   BOOL    advertised;             /* Set TRUE when advertised */
@@ -387,11 +444,13 @@ typedef struct auth_info {
     uschar *);                    /* rest of AUTH command */
   int (*clientcode)(              /* client function */
     struct auth_instance *,
-    struct smtp_inblock *,        /* socket and input buffer */
-    struct smtp_outblock *,       /* socket and output buffer */
+    void *,                      /* smtp conn, with socket, output and input buffers */
     int,                          /* command timeout */
     uschar *,                     /* buffer for reading response */
     int);                         /* sizeof buffer */
+  gstring * (*version_report)(    /* diagnostic version reporting */
+    gstring *);                   /* string to append to */
+  void (*macros_create)(void);   /* feature-macro creation */
 } auth_info;
 
 
@@ -404,13 +463,14 @@ typedef struct ip_address_item {
   int    port;
   BOOL   v6_include_v4;            /* Used in the daemon */
   uschar address[46];
+  uschar * log;                           /* portion of "listening on" log line */
 } ip_address_item;
 
 /* Structure for chaining together arbitrary strings. */
 
 typedef struct string_item {
-  struct string_item *next;
-  uschar *text;
+  struct string_item * next;
+  uschar *             text;
 } string_item;
 
 /* Information about a soft delivery failure, for use when calculating
@@ -469,44 +529,16 @@ typedef struct address_item_propagated {
   uschar *errors_address;         /* where to send errors (NULL => sender) */
   header_line *extra_headers;     /* additional headers */
   uschar *remove_headers;         /* list of those to remove */
+  void   *variables;             /* router-vasriables */
 
-  #ifdef EXPERIMENTAL_SRS
-  uschar *srs_sender;             /* Change return path when delivering */
-  #endif
+  BOOL    ignore_error:1;        /* ignore delivery error */
+#ifdef SUPPORT_I18N
+  BOOL    utf8_msg:1;            /* requires SMTPUTF8 processing */
+  BOOL   utf8_downcvt:1;         /* mandatory downconvert on delivery */
+  BOOL   utf8_downcvt_maybe:1;   /* optional downconvert on delivery */
+#endif
 } address_item_propagated;
 
-/* Bits for the flags field below */
-
-#define af_allow_file          0x00000001 /* allow file in generated address */
-#define af_allow_pipe          0x00000002 /* allow pipe in generated address */
-#define af_allow_reply         0x00000004 /* allow autoreply in generated address */
-#define af_dr_retry_exists     0x00000008 /* router retry record exists */
-#define af_expand_pipe         0x00000010 /* expand pipe arguments */
-#define af_file                0x00000020 /* file delivery; always with pfr */
-#define af_gid_set             0x00000040 /* gid field is set */
-#define af_home_expanded       0x00000080 /* home_dir is already expanded */
-#define af_ignore_error        0x00000100 /* ignore delivery error */
-#define af_initgroups          0x00000200 /* use initgroups() for local transporting */
-#define af_local_host_removed  0x00000400 /* local host was backup */
-#define af_lt_retry_exists     0x00000800 /* local transport retry exists */
-#define af_pfr                 0x00001000 /* pipe or file or reply delivery */
-#define af_retry_skipped       0x00002000 /* true if retry caused some skipping */
-#define af_retry_timedout      0x00004000 /* true if retry timed out */
-#define af_uid_set             0x00008000 /* uid field is set */
-#define af_hide_child          0x00010000 /* hide child in bounce/defer msgs */
-#define af_sverify_told        0x00020000 /* sender verify failure notified */
-#define af_verify_pmfail       0x00040000 /* verify failure was postmaster callout */
-#define af_verify_nsfail       0x00080000 /* verify failure was null sender callout */
-#define af_homonym             0x00100000 /* an ancestor has same address */
-#define af_verify_routed       0x00200000 /* for cached sender verify: routed OK */
-#define af_verify_callout      0x00400000 /* for cached sender verify: callout was specified */
-#define af_include_affixes     0x00800000 /* delivered with affixes in RCPT */
-#define af_cert_verified       0x01000000 /* delivered with verified TLS cert */
-#define af_pass_message        0x02000000 /* pass message in bounces */
-
-/* These flags must be propagated when a child is created */
-
-#define af_propagate           (af_ignore_error)
 
 /* The main address structure. Note that fields that are to be copied to
 generated addresses should be put in the address_item_propagated structure (see
@@ -535,8 +567,10 @@ typedef struct address_item {
   uschar *lc_local_part;          /* lowercased local part */
   uschar *local_part;             /* points to cc or lc version */
   uschar *prefix;                 /* stripped prefix of local part */
+  uschar *prefix_v;              /*  variable part of above */
   uschar *suffix;                 /* stripped suffix of local part */
-  uschar *domain;                 /* working domain (lower cased) */
+  uschar *suffix_v;              /*  variable part of above */
+  const uschar *domain;           /* working domain (lower cased) */
 
   uschar *address_retry_key;      /* retry key including full address */
   uschar *domain_retry_key;       /* retry key for domain only */
@@ -552,23 +586,92 @@ typedef struct address_item {
   uschar *self_hostname;          /* after self=pass */
   uschar *shadow_message;         /* info about shadow transporting */
 
-  #ifdef SUPPORT_TLS
+#ifndef DISABLE_TLS
+  const uschar *tlsver;           /* version used for transport */
   uschar *cipher;                 /* Cipher used for transport */
+  void   *ourcert;                /* Certificate offered to peer, binary */
+  void   *peercert;               /* Certificate from peer, binary */
   uschar *peerdn;                 /* DN of server's certificate */
-  #endif
+  int    ocsp;                   /* OCSP status of peer cert */
+#endif
+
+#ifdef EXPERIMENTAL_DSN_INFO
+  const uschar *smtp_greeting;   /* peer self-identification */
+  const uschar *helo_response;   /* peer message */
+#endif
+
+  uschar *authenticator;         /* auth driver name used by transport */
+  uschar *auth_id;               /* auth "login" name used by transport */
+  uschar *auth_sndr;             /* AUTH arg to SMTP MAIL, used by transport */
+
+  uschar *dsn_orcpt;              /* DSN orcpt value */
+  int     dsn_flags;              /* DSN flags */
+  int     dsn_aware;              /* DSN aware flag */
 
   uid_t   uid;                    /* uid for transporting */
   gid_t   gid;                    /* gid for transporting */
 
-  unsigned int flags;             /* a row of bits, defined above */
+                                 /* flags */
+  struct {
+    BOOL af_allow_file:1;              /* allow file in generated address */
+    BOOL af_allow_pipe:1;              /* allow pipe in generated address */
+    BOOL af_allow_reply:1;             /* allow autoreply in generated address */
+    BOOL af_dr_retry_exists:1;         /* router retry record exists */
+    BOOL af_expand_pipe:1;             /* expand pipe arguments */
+    BOOL af_file:1;                    /* file delivery; always with pfr */
+    BOOL af_gid_set:1;                 /* gid field is set */
+    BOOL af_home_expanded:1;           /* home_dir is already expanded */
+    BOOL af_initgroups:1;              /* use initgroups() for local transporting */
+    BOOL af_local_host_removed:1;      /* local host was backup */
+    BOOL af_lt_retry_exists:1;         /* local transport retry exists */
+    BOOL af_pfr:1;                     /* pipe or file or reply delivery */
+    BOOL af_retry_skipped:1;           /* true if retry caused some skipping */
+    BOOL af_retry_timedout:1;          /* true if retry timed out */
+    BOOL af_uid_set:1;                 /* uid field is set */
+    BOOL af_hide_child:1;              /* hide child in bounce/defer msgs */
+    BOOL af_sverify_told:1;            /* sender verify failure notified */
+    BOOL af_verify_pmfail:1;           /* verify failure was postmaster callout */
+    BOOL af_verify_nsfail:1;           /* verify failure was null sender callout */
+    BOOL af_homonym:1;                 /* an ancestor has same address */
+    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 */
+    BOOL af_tcp_fastopen_conn:1;       /* delivery connection used TCP Fast Open */
+    BOOL af_tcp_fastopen:1;            /* delivery usefully used TCP Fast Open */
+    BOOL af_tcp_fastopen_data:1;       /* delivery sent SMTP commands on TCP Fast Open */
+    BOOL af_pipelining:1;              /* delivery used (traditional) pipelining */
+#ifndef DISABLE_PIPE_CONNECT
+    BOOL af_early_pipe:1;              /* delivery used connect-time pipelining */
+#endif
+#ifndef DISABLE_PRDR
+    BOOL af_prdr_used:1;               /* delivery used SMTP PRDR */
+#endif
+    BOOL af_chunking_used:1;           /* delivery used SMTP CHUNKING */
+    BOOL af_force_command:1;           /* force_command in pipe transport */
+#ifdef SUPPORT_DANE
+    BOOL af_dane_verified:1;           /* TLS cert verify done with DANE */
+#endif
+#ifdef SUPPORT_I18N
+    BOOL af_utf8_downcvt:1;            /* downconvert was done for delivery */
+#endif
+#ifndef DISABLE_TLS_RESUME
+    BOOL af_tls_resume:1;              /* TLS used a resumed session */
+#endif
+  } flags;
+
   unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32];
   unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32];
   int     mode;                   /* mode for local transporting to a file */
+  int    basic_errno;            /* status after failure */
   int     more_errno;             /* additional error information */
-                                  /* (may need to hold a timestamp) */
+  struct timeval delivery_time;   /* time taken to do delivery/attempt */
 
-  short int basic_errno;          /* status after failure */
-  short int child_count;          /* number of child addresses */
+  unsigned short child_count;     /* number of child addresses */
   short int return_file;          /* fileno of return data file */
   short int special_action;       /* ( used when when deferred or failed */
                                   /* (  also  */
@@ -576,7 +679,7 @@ typedef struct address_item {
                                   /* (  also  */
                                   /* ( contains verify rc in sender verify cache */
   short int transport_return;     /* result of delivery attempt */
-  address_item_propagated p;      /* fields that are propagated to children */
+  address_item_propagated prop;   /* fields that are propagated to children */
 } address_item;
 
 /* The table of header names consists of items of this type */
@@ -592,7 +695,7 @@ typedef struct {
 
 typedef struct error_block {
   struct error_block *next;
-  uschar *text1;
+  const uschar *text1;
   uschar *text2;
 } error_block;
 
@@ -637,6 +740,22 @@ typedef struct tree_node {
   uschar  name[1];                /* node name - variable length */
 } tree_node;
 
+/* Structure for holding time-limited data such as DNS returns.
+We use this rather than extending tree_node to avoid wasting
+space for most tree use (variables...) at the cost of complexity
+for the lookups cache.
+We also store any options used for the lookup. */
+
+typedef struct expiring_data {
+  time_t       expiry;         /* if nonzero, data invalid after this time */
+  const uschar * opts;         /* options, or NULL */
+  union
+    {
+    void  *    ptr;            /* pointer to data */
+    int                val;            /* or integer data */
+    } data;
+} expiring_data;
+
 /* Structure for holding the handle and the cached last lookup for searches.
 This block is pointed to by the tree entry for the file. The file can get
 closed if too many are opened at once. There is a LRU chain for deciding which
@@ -654,26 +773,28 @@ typedef struct search_cache {
 uncompressed, but the data pointer is into the raw data. */
 
 typedef struct {
-  uschar  name[DNS_MAXNAME];      /* domain name */
-  int     type;                   /* record type */
-  int     size;                   /* size of data */
-  uschar *data;                   /* pointer to data */
+  uschar        name[DNS_MAXNAME];      /* domain name */
+  int           type;                   /* record type */
+  unsigned short ttl;                  /* time-to-live, seconds */
+  int           size;                   /* size of data */
+  const uschar *data;                   /* pointer to data */
 } dns_record;
 
-/* Structure for holding the result of a DNS query. */
+/* Structure for holding the result of a DNS query.  A touch over
+64k big, so take care to release as soon as possible. */
 
 typedef struct {
   int     answerlen;              /* length of the answer */
-  uschar  answer[MAXPACKET];      /* the answer itself */
+  uschar  answer[NS_MAXMSG];      /* the answer itself */
 } dns_answer;
 
 /* Structure for holding the intermediate data while scanning a DNS answer
 block. */
 
 typedef struct {
-  int     rrcount;                /* count of RRs in the answer */
-  uschar *aptr;                   /* pointer in the answer while scanning */
-  dns_record srr;                 /* data from current record in scan */
+  int            rrcount;         /* count of RRs in the answer */
+  const uschar *aptr;             /* pointer in the answer while scanning */
+  dns_record     srr;             /* data from current record in scan */
 } dns_scan;
 
 /* Structure for holding a chain of IP addresses that are extracted from
@@ -701,15 +822,40 @@ md5;
 typedef struct sha1 {
   unsigned int H[5];
   unsigned int length;
-  }
-sha1;
+} sha1;
+
+/* Information for making an smtp connection */
+typedef struct {
+  transport_instance *  tblock;
+  void *               ob;     /* smtp_transport_options_block * */
+  host_item *           host;
+  int                   host_af;
+  uschar *              interface;
+
+  int                  sock;   /* used for a bound but not connected socket */
+  uschar *             sending_ip_address;     /* used for TLS resumption */
+  const uschar *       host_lbserver;          /* ditto, for server-behind LB */
+  BOOL                 have_lbserver:1;        /* host_lbserver is valid */
+
+#ifdef SUPPORT_DANE
+  BOOL dane:1;                 /* connection must do dane */
+  dns_answer           tlsa_dnsa;      /* strictly, this should use tainted mem */
+#endif
+} smtp_connect_args;
+
+/* A client-initiated connection. If TLS, the second element is non-NULL */
+typedef struct {
+  int  sock;
+  void * tls_ctx;
+} client_conn_ctx;
+
 
 /* Structure used to hold incoming packets of SMTP responses for a specific
 socket. The packets which may contain multiple lines (and in some cases,
 multiple responses). */
 
 typedef struct smtp_inblock {
-  int     sock;                   /* the socket */
+  client_conn_ctx * cctx;        /* the connection */
   int     buffersize;             /* the size of the buffer */
   uschar *ptr;                    /* current position in the buffer */
   uschar *ptrend;                 /* end of data in the buffer */
@@ -721,12 +867,14 @@ specific socket. The packets which may contain multiple lines when pipelining
 is in use. */
 
 typedef struct smtp_outblock {
-  int     sock;                   /* the socket */
+  client_conn_ctx * cctx;        /* the connection */
   int     cmd_count;              /* count of buffered commands */
   int     buffersize;             /* the size of the buffer */
   BOOL    authenticating;         /* TRUE when authenticating */
   uschar *ptr;                    /* current position in the buffer */
   uschar *buffer;                 /* the buffer itself */
+
+  smtp_connect_args * conn_args;  /* to make connection, if not yet made */
 } smtp_outblock;
 
 /* Structure to hold information about the source of redirection information */
@@ -745,10 +893,10 @@ typedef struct redirect_block {
 /* Structure for passing arguments to check_host() */
 
 typedef struct check_host_block {
-  uschar *host_name;
-  uschar *host_address;
-  uschar *host_ipv4;
-  BOOL   negative;
+  const uschar *host_name;
+  const uschar *host_address;
+  const uschar *host_ipv4;
+  mcs_flags    flags;
 } check_host_block;
 
 /* Structure for remembering lookup data when caching the result of
@@ -763,27 +911,69 @@ typedef struct namedlist_cacheblock {
 /* Structure for holding data for an entry in a named list */
 
 typedef struct namedlist_block {
-  uschar *string;                    /* the list string */
-  namedlist_cacheblock *cache_data;  /* cached domain_data or localpart_data */
-  int number;                        /* the number of the list for caching */
+  const uschar *string;                        /* the list string */
+  namedlist_cacheblock *cache_data;    /* cached domain_data or localpart_data */
+  short                number;                 /* the number of the list for caching */
+  BOOL         hide;                   /* -bP does not display value */
 } namedlist_block;
 
 /* Structures for Access Control Lists */
 
 typedef struct acl_condition_block {
-  struct acl_condition_block *next;
-  uschar *arg;
-  int type;
+  struct acl_condition_block * next;
+  uschar *                     arg;
+  int                          type;
   union {
-    BOOL negated;
-    int varnumber;
+    BOOL       negated;
+    uschar *   varname;
   } u;
 } acl_condition_block;
 
 typedef struct acl_block {
-  struct acl_block *next;
-  acl_condition_block *condition;
-  int verb;
+  struct acl_block *   next;
+  acl_condition_block *        condition;
+  int                  verb;
+  int                  srcline;
+  const uschar *       srcfile;
 } acl_block;
 
+/* smtp transport calc outbound_ip */
+typedef BOOL (*oicf) (uschar *message_id, void *data);
+
+/* DKIM information for transport */
+struct ob_dkim {
+  uschar *dkim_domain;
+  uschar *dkim_identity;
+  uschar *dkim_private_key;
+  uschar *dkim_selector;
+  uschar *dkim_canon;
+  uschar *dkim_sign_headers;
+  uschar *dkim_strict;
+  uschar *dkim_hash;
+  uschar *dkim_timestamps;
+  BOOL    dot_stuffed;
+  BOOL    force_bodyhash;
+#ifdef EXPERIMENTAL_ARC
+  uschar *arc_signspec;
+#endif
+};
+
+
+/* per-queue-runner info */
+typedef struct qrunner {
+  struct qrunner * next;       /* list sorted by next tick */
+
+  uschar *     name;           /* NULL for the default queue */
+  unsigned     interval;       /* tick rate, seconds */
+  time_t       next_tick;      /* next run should, or should have, start(ed) */
+  unsigned     run_max;        /* concurrent queue runner limit */
+  unsigned     run_count;      /* current runners */
+
+  BOOL queue_run_force :1;
+  BOOL deliver_force_thaw :1;
+  BOOL queue_run_first_delivery :1;
+  BOOL queue_run_local :1;
+  BOOL queue_2stage :1;
+} qrunner;
+
 /* End of structs.h */