[exim-dev] [PATCH] log_selector +outgoing_interface

Góra strony
Delete this message
Reply to this message
Autor: Tony Finch
Data:  
Dla: exim-dev
CC: jgh146exb
Temat: [exim-dev] [PATCH] log_selector +outgoing_interface
Add a separate outgoing_interface log selector, for consistency with
+incoming_interface +incoming_port +outgoing_port, and move the interface
field on => lines after the remote host for consistency with <= lines.

I have also expanded the log selector variables to three words since the
second word was very nearly full.

---
 doc/doc-docbook/spec.xfpt | 25 +++++++++++++++++--------
 doc/doc-txt/ChangeLog     |  3 +++
 src/src/deliver.c         | 11 +++++++----
 src/src/exim.c            |  8 ++++----
 src/src/functions.h       |  4 ++--
 src/src/globals.c         |  8 ++++++--
 src/src/globals.h         |  1 +
 src/src/log.c             | 32 ++++++++++++++++++++++----------
 src/src/macros.h          |  9 +++++++--
 9 files changed, 69 insertions(+), 32 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 3e36520..deaca14 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -35447,11 +35447,12 @@ selection marked by asterisks:
 &`*etrn                       `&  ETRN commands
 &`*host_lookup_failed         `&  as it says
 &` ident_timeout              `&  timeout for ident connection
-.new
-&` incoming_interface         `&  local interface on <= and => lines
-.wen
+&` incoming_interface         `&  local interface on <= lines
 &` incoming_port              `&  remote port on <= lines
 &`*lost_incoming_connection   `&  as it says (includes timeouts)
+.new
+&` outgoing_interface         `&  local interface on => lines
+.wen
 &` outgoing_port              `&  add remote port to => lines
 &`*queue_run                  `&  start and end queue runs
 &` queue_time                 `&  time on queue for one recipient
@@ -35576,11 +35577,8 @@ client's ident port times out.
 &%incoming_interface%&: The interface on which a message was received is added
 to the &"<="& line as an IP address in square brackets, tagged by I= and
 followed by a colon and the port number. The local interface and port are also
-added to other SMTP log lines, for example &"SMTP connection from"& and to
-rejection lines
-.new
-and (despite the name) the local interface is added to &"=>"& lines..
-.wen
+added to other SMTP log lines, for example &"SMTP connection from"&, and to
+rejection lines.
 .next
 .cindex "log" "incoming remote port"
 .cindex "port" "logging remote"
@@ -35598,6 +35596,17 @@ important with the widening use of NAT (see RFC 2505).
 &%lost_incoming_connection%&: A log line is written when an incoming SMTP
 connection is unexpectedly dropped.
 .next
+.cindex "log" "outgoing interface"
+.cindex "log" "local interface"
+.cindex "log" "local address and port"
+.cindex "TCP/IP" "logging local address and port"
+.cindex "interface" "logging"
+.new
+&%outgoing_interface%&: The interface on which a message was sent is added
+to delivery lines as an IP address in square brackets, tagged by I= and
+followed by a colon and the port number.
+.wen
+.next
 .cindex "log" "outgoing remote port"
 .cindex "port" "logging outgoint remote"
 .cindex "TCP/IP" "logging ougtoing remote port"
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 2c34c21..5e8a092 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -121,6 +121,9 @@ JH/35 Bug 1642: Fix support of $spam_ variables at delivery time.  Was
 JH/36 Bug 1659: Guard checking of input smtp commands again pseudo-command
       added for tls authenticator.


+TF/01 Add a separate outgoing_interface log selector, and move the interface
+      field after the remote host for consistency with incoming_interface.
+


Exim version 4.85
-----------------
diff --git a/src/src/deliver.c b/src/src/deliver.c
index e77c47e..5d7e9e4 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -817,10 +817,6 @@ else
s = string_append(s, &size, &ptr, 2, US"> ", log_address);
}

-if (log_extra_selector & LX_incoming_interface  &&  sending_ip_address)
-  s = string_append(s, &size, &ptr, 3, US" I=[", sending_ip_address, US"]");
-  /* for the port:  string_sprintf("%d", sending_port) */
-
 if ((log_extra_selector & LX_sender_on_delivery) != 0  ||  msg)
   s = string_append(s, &size, &ptr, 3, US" F=<",
 #ifdef EXPERIMENTAL_INTERNATIONAL
@@ -891,6 +887,13 @@ else
 #endif
     }


+if ((log_ultra_selector & LY_outgoing_interface) &&
+    sending_ip_address != NULL)
+  {
+  uschar *ss = string_sprintf(" I=[%s]:%d", sending_ip_address, sending_port);
+  s = string_cat(s, &size, &ptr, ss, Ustrlen(ss));
+  }
+
 #ifdef SUPPORT_TLS
   s = d_tlslog(s, &size, &ptr, addr);
 #endif
diff --git a/src/src/exim.c b/src/src/exim.c
index f9d57ab..018c645 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -2451,8 +2451,8 @@ for (i = 1; i < argc; i++)
         argrest++;
         }
       if (*argrest != 0)
-        decode_bits(&selector, NULL, D_memory, 0, argrest, debug_options,
-          debug_options_count, US"debug", 0);
+        decode_bits(&selector, NULL, NULL, D_memory, 0, 0, argrest,
+          debug_options, debug_options_count, US"debug", 0);
       debug_selector = selector;
       }
     break;
@@ -3787,8 +3787,8 @@ else


/* Handle the decoding of logging options. */

-decode_bits(&log_write_selector, &log_extra_selector, 0, 0,
- log_selector_string, log_options, log_options_count, US"log", 0);
+decode_bits(&log_write_selector, &log_extra_selector, &log_ultra_selector,
+ 0, 0, 0, log_selector_string, log_options, log_options_count, US"log", 0);

 DEBUG(D_any)
   {
diff --git a/src/src/functions.h b/src/src/functions.h
index ee42a27..a6f451e 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -123,8 +123,8 @@ extern void    debug_print_ids(uschar *);
 extern void    debug_print_string(uschar *);
 extern void    debug_print_tree(tree_node *);
 extern void    debug_vprintf(const char *, va_list);
-extern void    decode_bits(unsigned int *, unsigned int *,
-                  int, int, uschar *, bit_table *, int, uschar *, int);
+extern void    decode_bits(unsigned int *, unsigned int *, unsigned int *,
+               int, int, int, uschar *, bit_table *, int, uschar *, int);
 extern address_item *deliver_make_addr(uschar *, BOOL);
 extern void    deliver_init(void);
 extern void    delivery_log(int, address_item *, int, uschar *);
diff --git a/src/src/globals.c b/src/src/globals.c
index 66baffe..c37a34d 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -814,6 +814,7 @@ tree_node *localpartlist_anchor= NULL;
 int     localpartlist_count    = 0;
 uschar *log_buffer             = NULL;
 unsigned int log_extra_selector = LX_default;
+unsigned int log_ultra_selector = LY_default;
 uschar *log_file_path          = US LOG_FILE_PATH
                            "\0<--------------Space to patch log_file_path->";


@@ -821,9 +822,11 @@ uschar *log_file_path          = US LOG_FILE_PATH
 are the ones that get put into log_write_selector. They can be used in calls to
 log_write() to test for the bit. The options with LX_xxx identifiers have
 values greater than 0x80000000 and are put into log_extra_selector (without the
-top bit). They are never used in calls to log_write(), but are tested
+top bit). Similarly the LY_xxx identifiers have values greater than 0xC0000000
+and are put into log_ultra_selector (without the top bits). The LX_ and LY_
+values are never used in calls to log_write(), but are tested
 independently. This separation became necessary when the number of log
-selectors was getting close to filling a 32-bit word. */
+selectors nearly overflowed twice. */


/* Note that this list must be in alphabetical order. */

@@ -845,6 +848,7 @@ bit_table log_options[]        = {
   { US"incoming_interface",           LX_incoming_interface },
   { US"incoming_port",                LX_incoming_port },
   { US"lost_incoming_connection",     L_lost_incoming_connection },
+  { US"outgoing_interface",           LY_outgoing_interface },
   { US"outgoing_port",                LX_outgoing_port },
   { US"pid",                          LX_pid },
 #ifdef EXPERIMENTAL_PROXY
diff --git a/src/src/globals.h b/src/src/globals.h
index ab03302..bde8a71 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -532,6 +532,7 @@ extern tree_node *localpartlist_anchor;/* Tree of defined localpart lists */
 extern int     localpartlist_count;    /* Number defined */
 extern uschar *log_buffer;             /* For constructing log entries */
 extern unsigned int log_extra_selector;/* Bit map of logging options other than used by log_write() */
+extern unsigned int log_ultra_selector;/* Logging options overflowed two words */
 extern uschar *log_file_path;          /* If unset, use default */
 extern bit_table log_options[];        /* Table of options */
 extern int     log_options_count;      /* Size of table */
diff --git a/src/src/log.c b/src/src/log.c
index 11b3edf..3098fb5 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -1152,8 +1152,9 @@ intended for user use. It's an easy way for Exim to pass the debug settings
 when it is re-exec'ed.


The log options are held in two unsigned ints (because there became too many
-for one). The top bit in the table means "put in 2nd selector". This does not
-yet apply to debug options, so the "=" facility sets only the first selector.
+for one). The top bit in the table means "put in 2nd selector". The top two
+bits together mean "put in 3rd selector". This does not yet apply to debug
+options, so the "=" facility sets only the first selector.

 The "all" selector, which must be equal to 0xffffffff, is recognized specially.
 It sets all the bits in both selectors. However, there is a facility for then
@@ -1167,8 +1168,10 @@ we treat it as an unknown option: error message to stderr and die.
 Arguments:
   selector1      address of the first bit string
   selector2      address of the second bit string, or NULL
+  selector3      address of the third bit string, or NULL
   notall1        bits to exclude from "all" for selector1
   notall2        bits to exclude from "all" for selector2
+  notall3        bits to exclude from "all" for selector3
   string         the configured string
   options        the table of option names
   count          size of table
@@ -1179,8 +1182,9 @@ Returns:         nothing on success - bomb out on failure
 */


 void
-decode_bits(unsigned int *selector1, unsigned int *selector2, int notall1,
-  int notall2, uschar *string, bit_table *options, int count, uschar *which,
+decode_bits(unsigned int *selector1, unsigned int *selector2,
+  unsigned int *selector3, int notall1, int notall2, int notall3,
+  uschar *string, bit_table *options, int count, uschar *which,
   int flags)
 {
 uschar *errmsg;
@@ -1244,24 +1248,32 @@ else for(;;)
           if (adding)
             {
             *selector1 = 0xffffffff ^ notall1;
-            if (selector2 != NULL) *selector2 = 0x7fffffff ^ notall2;
+            if (selector2 != NULL) *selector2 = 0x3fffffff ^ notall2;
+            if (selector3 != NULL) *selector3 = 0x3fffffff ^ notall2;
             }
           else
             {
             *selector1 = 0;
             if (selector2 != NULL) *selector2 = 0;
+            if (selector3 != NULL) *selector3 = 0;
             }
           }


-        /* Otherwise, the 0x80000000 bit means "this value, without the top
-        bit, belongs in the second selector". */
+        /* Otherwise, the 0xC0000000 bits mean "this value, without the top
+        bit, belongs in the third selector", and the 0x80000000 bit indicates
+        the second selector. */


         else
           {
-          if ((bit & 0x80000000) != 0)
+          if ((bit & 0xC0000000) == 0xC0000000)
+            {
+            selector = selector3;
+            bit &= 0x3fffffff;
+            }
+          if ((bit & 0x80000000) == 0x80000000)
             {
             selector = selector2;
-            bit &= 0x7fffffff;
+            bit &= 0x3fffffff;
             }
           else selector = selector1;
           if (adding) *selector |= bit; else *selector &= ~bit;
@@ -1336,7 +1348,7 @@ if (tag_name != NULL && (Ustrchr(tag_name, '/') != NULL))
 debug_selector = D_default;
 if (opts)
   {
-  decode_bits(&debug_selector, NULL, D_memory, 0, opts,
+  decode_bits(&debug_selector, NULL, NULL, D_memory, 0, 0, opts,
       debug_options, debug_options_count, US"debug", DEBUG_FROM_CONFIG);
   }


diff --git a/src/src/macros.h b/src/src/macros.h
index 61f9ca6..5a0a73d 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -382,9 +382,10 @@ handle this here. It is fudged externally. */

/* Options bits for logging. Those that will end up in log_write_selector have
values < 0x80000000. They can be used in calls to log_write(). The others have
-values > 0x80000000 and are put into log_extra_selector (without the top bit).
+values > 0x80000000 and are put into log_extra_selector (without the top bits)
+and values > 0xC0000000 are put into log_ultra_selector (without the top bits).
These are only ever tested independently. "All" is a magic value that is used
-only in the name table to set all options in both bit maps. */
+only in the name table to set all options in the bit maps. */

 /* The L_all value must always have all bits set, as it is recognized specially
 by the function that decodes debug and log selectors. This is to enable it to
@@ -438,6 +439,8 @@ set all the bits in a multi-word selector. */
 #define LX_smtp_mailauth               0x84000000
 #define LX_proxy                       0x88000000


+#define LY_outgoing_interface          0xC0000001
+
 #define L_default     (L_connection_reject        | \
                        L_delay_delivery           | \
                        L_dnslist_defer            | \
@@ -456,6 +459,8 @@ set all the bits in a multi-word selector. */
                        LX_tls_certificate_verified| \
                        LX_tls_cipher) & 0x7fffffff)


+#define LY_default 0
+
/* Private error numbers for delivery failures, set negative so as not
to conflict with system errno values. */

--
2.4.0.6.g7b34ee4