]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.2-20040917
authorWietse Venema <wietse@porcupine.org>
Fri, 17 Sep 2004 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:29:53 +0000 (06:29 +0000)
24 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/conf/canonical
postfix/html/canonical.5.html
postfix/html/postconf.5.html
postfix/html/scache.8.html
postfix/makedefs
postfix/man/man5/canonical.5
postfix/man/man5/postconf.5
postfix/mantools/postlink
postfix/proto/canonical
postfix/proto/postconf.proto
postfix/src/bounce/bounce_notify_util.c
postfix/src/global/mail_version.h
postfix/src/global/scache.c
postfix/src/global/scache.h
postfix/src/global/scache_clnt.c
postfix/src/global/scache_multi.c
postfix/src/global/scache_multi.ref
postfix/src/global/scache_single.c
postfix/src/scache/scache.c
postfix/src/smtp/smtp_reuse.c
postfix/src/util/sys_defs.h

index 6c604ed34244bd1b62d9fe7f3de5002ac8d91955..442d5ed0b9425833de83f787c046da95494326fc 100644 (file)
@@ -1,4 +1,3 @@
--TSCACHE_HEAD_NODE
 -TABOUNCE
 -TALIAS_TOKEN
 -TANVIL_LOCAL
 -TSCACHE_SINGLE
 -TSCACHE_SINGLE_DEST
 -TSCACHE_SINGLE_ENDP
+-TSCACHE_SIZE
 -TSCAN_DIR
 -TSCAN_INFO
 -TSCAN_OBJ
index 6834bb57a14f4592ec701ed7ee3b6a6d75dd9c24..ae41bf429576eed2a5ec3eff6e73269bbe6d8ce1 100644 (file)
@@ -9587,9 +9587,9 @@ Apologies for any names omitted.
 
 20040723
 
-       Bug? Safety? spawn(8) did not reject a user with the -1
-       UID value, so the command could run as root.  Files:
-       util/spawn_command.c, src/util/spawn.c.
+       Safety: spawn(8) now rejects a user with the -1 UID or GID
+       value, so that commands will not end up running as root.
+       Files:  util/spawn_command.c, spawn/spawn.c.
 
        User interface: parameter smtp_connection_cache_domains
        renamed to smtp_connection_cache_destinations. Destinations
@@ -9706,9 +9706,36 @@ Apologies for any names omitted.
        Portability: Solaris closefrom() support didn't work for
        non-SUN compilers. Victor Duchovni, Morgan Stanley.
 
+20040830
+
+       Feature: the scache(8) session cache manager now logs the
+       peak counts of destinations, endpoints and sessions. Files:
+       scache/scache.c, global/scache*c.
+
+20040831
+
+       Portability: disable session caching support on SCO 5
+       because of incompatible sockets API. File: util/sys_defs.h.
+
+20040913
+
+       Bugfix (introduced 20020803): sent the wrong bounce message
+       type when a Delivered-To: loop was detected for a mailing
+       list alias.  Nicolas Riendeau. File: bounce_notify_util.c.
+
 Open problems:
 
-       Low: scache & anvil should log cache peak sizes.
+       Low: should the Delivered-To: test in local(8) be configurable?
+
+       Low: append a different domain (like, address.invalid) for
+       mail from clients not in mynetworks.
+
+       Low: document propagate_unmatched_extensions in aliases(5)
+       etc.
+
+       Low: make mail_addr_find() lookup configurable.
+
+       Low: anvil(8) should log cache peak size, like scache(8).
 
        Low: update events.c so that 1-second timer requests do
        not suffer from rounding errors. This is needed for 1-second
index c5df8ee68abddc74e4128f3f9e7f3bedec3a5117..01ac15a2207caae84bdc68ecef24095108653fcc 100644 (file)
@@ -13,7 +13,7 @@ Incompatible changes with snapshot Postfix-2.2-20040829
 When no recipients are specified on the command line or via the -t
 option, the Postfix sendmail command terminates with status EX_USAGE
 and produces an error message instead of accepting the mail first
-and bouncing it later. This gives direct more feedback in case of
+and bouncing it later. This gives more direct feedback in case of
 a common client configuration error.
 
 Major changes with snapshot Postfix-2.2-20040827
index f47535da68b392bcdf21b02bb21670dc0fe3163e..0445a0d5caa698c2dd40845c18c52a8407b6a111 100644 (file)
 #        Sendmail rule set S3, if you  like.   This  is  controlled
 #        with the canonical_classes parameter.
 # 
-#        The   canonical   mapping   affects  both  message  header
-#        addresses (i.e. addresses that appear inside messages) and
-#        message  envelope  addresses  (for  example, the addresses
-#        that are used in SMTP protocol commands).  Think  Sendmail
-#        rule set S3, if you like.
-# 
 #        Typically,  one  would  use the canonical table to replace
 #        login  names  by  Firstname.Lastname,  or  to   clean   up
 #        addresses produced by legacy mail systems.
index fbfc983246ab5ccc4429b890ee602ad1a495ab8a..54106f599aff53a673f59c76d36ab83cce9d064c 100644 (file)
@@ -44,13 +44,7 @@ CANONICAL(5)                                         CANONICAL(5)
        sages) and message envelope addresses  (for  example,  the
        addresses  that are used in SMTP protocol commands). Think
        Sendmail rule set <b>S3</b>, if you  like.   This  is  controlled
-       with the <b>canonical_classes</b> parameter.
-
-       The   <b>canonical</b>   mapping   affects  both  message  header
-       addresses (i.e. addresses that appear inside messages) and
-       message  envelope  addresses  (for  example, the addresses
-       that are used in SMTP protocol commands).  Think  Sendmail
-       rule set <b>S3</b>, if you like.
+       with the <b><a href="postconf.5.html#canonical_classes">canonical_classes</a></b> parameter.
 
        Typically,  one  would  use the <b>canonical</b> table to replace
        login  names  by  <i>Firstname.Lastname</i>,  or  to   clean   up
@@ -160,7 +154,7 @@ CANONICAL(5)                                         CANONICAL(5)
        The text below provides  only  a  parameter  summary.  See
        <a href="postconf.5.html">postconf(5)</a> for more details including examples.
 
-       <b>canonical_classes</b>
+       <b><a href="postconf.5.html#canonical_classes">canonical_classes</a></b>
               What  addresses  are  subject  to canonical address
               mapping.
 
index 8f186a332a35c752eb36143270a5b24683cc77ab..ee5633105ea40e8821640110442e581f976bdba8 100644 (file)
@@ -4993,10 +4993,10 @@ optional address extension.
 address extension.
 
 <li> Look up the "user+extension" address local part when the
-recipient domain equals $<a href="postconf.5.html#myorigin">myorigin</a>, $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a>
+sender domain equals $<a href="postconf.5.html#myorigin">myorigin</a>, $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a>
 or $<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
 
-<li> Look up the "user" address local part when the recipient domain
+<li> Look up the "user" address local part when the sender domain
 equals $<a href="postconf.5.html#myorigin">myorigin</a>, $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or $<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
 
 <li> Look up the "@domain.tld" part.
@@ -6224,18 +6224,27 @@ a restriction list, to make the default policy explicit.</dd>
 <dd>Reject the request when the envelope sender is the null address,
 and the message has multiple envelope recipients. Although this
 usage is technically allowed, it seems to have no legitimate
-application. <br> The <a href="postconf.5.html#multi_recipient_bounce_reject_code">multi_recipient_bounce_reject_code</a> parameter
-specifies the response code for rejected requests (default: 550).
-This feature is available in Postfix 2.1 and later. </dd>
+application. <br> NOTE: this restriction can only work reliably
+when used in <a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a>, because the total number of
+recipients is not known at an earlier stage of the SMTP conversation.
+Use at the RCPT stage will only reject the second etc.  recipient.
+<br>
+The <a href="postconf.5.html#multi_recipient_bounce_reject_code">multi_recipient_bounce_reject_code</a> parameter specifies the
+response code for rejected requests (default:  550).  This feature
+is available in Postfix 2.1 and later. </dd>
 
 <dt><b><a name="reject_unauth_pipelining">reject_unauth_pipelining</a></b></dt>
 
 <dd>Reject the request when the client sends SMTP commands ahead
 of time where it is not allowed, or when the client sends SMTP
 commands ahead of time without knowing that Postfix actually supports
-SMTP command pipelining. This stops mail from bulk mail software
-that improperly uses SMTP command pipelining in order to speed up
-deliveries.</dd>
+ESMTP command pipelining. This stops mail from bulk mail software
+that improperly uses ESMTP command pipelining in order to speed up
+deliveries. <br> NOTE: <a href="postconf.5.html#reject_unauth_pipelining">reject_unauth_pipelining</a> is not useful
+outside <a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> when 1) the client uses ESMTP (EHLO
+instead of HELO) and 2) with "<a href="postconf.5.html#smtpd_delay_reject">smtpd_delay_reject</a> = yes" (the
+default).  The use of <a href="postconf.5.html#reject_unauth_pipelining">reject_unauth_pipelining</a> in the other
+restriction contexts is therefore not recommended.  </dd>
 
 <dt><b><a name="reject">reject</a></b></dt>
 
index 92d73f05136ed85c1b237b5844f2cb0c5c2157a4..79cb1f0d99dab73e9dee899cd0af594b46062eb2 100644 (file)
@@ -97,7 +97,7 @@ SCACHE(8)                                               SCACHE(8)
               The  maximal  time-to-live  value  that the session
               cache server allows.
 
-       <b>session_cache_status_update_time (600s)</b>
+       <b><a href="postconf.5.html#session_cache_status_update_time">session_cache_status_update_time</a> (600s)</b>
               How frequently  the  <a href="scache.8.html">scache(8)</a>  server  logs  usage
               statistics  with  session  cache hit and miss rates
               for logical  destinations  and  for  physical  end-
index 8cedde2c17159c6eef538d0297ad240c7c20ae1a..2ef53d797641c3a204ba8e2446ec6ba7391bdf65 100644 (file)
@@ -52,6 +52,19 @@ SYSLIBS=
 AR=ar
 ARFL=rv
 
+# Ugly function to make our error message more visible among the
+# garbage that is output by some versions of make(1).
+
+# By now all shells must have functions.
+
+error() {
+   # Alas, tput(1) is not portable so we can't use visual effects.
+   echo "ATTENTION:" 1>&2;
+   echo "ATTENTION:" $* 1>&2;
+   echo "ATTENTION:" 1>&2;
+   exit 1
+}
+
 SYSTEM=`(uname -s) 2>/dev/null`
 RELEASE=`(uname -r) 2>/dev/null`
 VERSION=`(uname -v) 2>/dev/null`
@@ -81,8 +94,7 @@ case "$SYSTEM.$RELEASE" in
                    RANLIB=echo
                    SYSLIBS="-lresolv -lsocket -lnsl -lc -L/usr/ucblib -lucb"
                    ;;
-             *) echo "Seems to be UnixWare`uname -v`. Untested." 1>&2; 
-                exit 1;;
+             *) error "Seems to be UnixWare`uname -v`. Untested.";;
                esac
                ;;
   FreeBSD.2*)  SYSTYPE=FREEBSD2
@@ -135,12 +147,12 @@ case "$SYSTEM.$RELEASE" in
                STRCASE="strcasecmp.o"
                # Avoid common types of braindamage
                case "$LD_LIBRARY_PATH" in
-               ?*) echo "Don't set LD_LIBRARY_PATH" 1>&2; exit 1;;
+               ?*) error "Don't set LD_LIBRARY_PATH";;
                esac
-               case "$CC" in
-               *ucb*) echo "Don't use /usr/ucb/cc or ucblib" 1>&2; exit 1;;
-                 cc*) case `which cc` in
-               *ucb*) echo "Don't use /usr/ucb/cc or ucblib" 1>&2; exit 1;;
+               case "${CC}" in
+               *ucb*) error "Don't use /usr/ucb/cc or ucblib";;
+                 cc*) case `which ${CC}` in
+               *ucb*) error "Don't use /usr/ucb/cc or ucblib";;
                  esac;;
                esac
                ;;
@@ -179,7 +191,7 @@ case "$SYSTEM.$RELEASE" in
                        esac
                        CCARGS="$CCARGS -D_ALL_SOURCE"
                        ;;
-               *)      echo "Unknown AIX version: `uname -v`." 1>&2; exit 1;;
+               *)      error "Unknown AIX version: `uname -v`.";;
                esac;;
                # Tested with RedHat 3.03 on 20020729.
     Linux.1*)  SYSTYPE=LINUX1
@@ -297,10 +309,10 @@ Rhapsody.5*|Darwin.*)
                    : ${CC=cc}
                    RANLIB="sleep 5; ranlib"
                else
-                   echo "Unable to determine your system type." 1>&2; exit 1
+                   error "Unable to determine your system type."
                fi
                ;;
-          *)   echo "Unknown system type: $SYSTEM $RELEASE" 1>&2; exit 1;;
+          *)   error "Unknown system type: $SYSTEM $RELEASE";;
 esac
 
 #
@@ -327,7 +339,7 @@ case "$CC" in
 */gcc|gcc) case `$CC -v` in
           "gcc version 2.8"*) : ${OPT=};;
           esac;;
-      *CC) echo "Don't use CC. That's the C++ compiler" 1>&2; exit 1;;
+      *CC) error "Don't use CC. That's the C++ compiler";;
         *) : ${OPT='-O'};;
 esac
 
index 544a8e20c1a082128d4cc70a43bbb9ece765e882..98b503d1ca4f5c476357bd2fa4df87a2c5f77611 100644 (file)
@@ -43,11 +43,6 @@ that are used in SMTP protocol commands). Think Sendmail
 rule set \fBS3\fR, if you like.  This is controlled with
 the \fBcanonical_classes\fR parameter.
 
-The \fBcanonical\fR mapping affects both message header addresses
-(i.e. addresses that appear inside messages) and message envelope
-addresses (for example, the addresses that are used in SMTP protocol
-commands). Think Sendmail rule set \fBS3\fR, if you like.
-
 Typically, one would use the \fBcanonical\fR table to replace login
 names by \fIFirstname.Lastname\fR, or to clean up addresses produced
 by legacy mail systems.
index 3ac34368fc28855b2626019a63caa6e5de473624..be65182464ef9fca7e0d39b84d4e5bf92e0bce8e 100644 (file)
@@ -2619,10 +2619,10 @@ Look up the "user@domain.tld" address without the optional
 address extension.
 .IP \(bu
 Look up the "user+extension" address local part when the
-recipient domain equals $myorigin, $mydestination, $inet_interfaces
+sender domain equals $myorigin, $mydestination, $inet_interfaces
 or $proxy_interfaces.
 .IP \(bu
-Look up the "user" address local part when the recipient domain
+Look up the "user" address local part when the sender domain
 equals $myorigin, $mydestination, $inet_interfaces or $proxy_interfaces.
 .IP \(bu
 Look up the "@domain.tld" part.
@@ -3286,16 +3286,27 @@ and the message has multiple envelope recipients. Although this
 usage is technically allowed, it seems to have no legitimate
 application.
 .br
-The multi_recipient_bounce_reject_code parameter
-specifies the response code for rejected requests (default: 550).
-This feature is available in Postfix 2.1 and later.
+NOTE: this restriction can only work reliably
+when used in smtpd_data_restrictions, because the total number of
+recipients is not known at an earlier stage of the SMTP conversation.
+Use at the RCPT stage will only reject the second etc.  recipient.
+.br
+The multi_recipient_bounce_reject_code parameter specifies the
+response code for rejected requests (default:  550).  This feature
+is available in Postfix 2.1 and later.
 .IP "\fBreject_unauth_pipelining\fR"
 Reject the request when the client sends SMTP commands ahead
 of time where it is not allowed, or when the client sends SMTP
 commands ahead of time without knowing that Postfix actually supports
-SMTP command pipelining. This stops mail from bulk mail software
-that improperly uses SMTP command pipelining in order to speed up
+ESMTP command pipelining. This stops mail from bulk mail software
+that improperly uses ESMTP command pipelining in order to speed up
 deliveries.
+.br
+NOTE: reject_unauth_pipelining is not useful
+outside smtpd_data_restrictions when 1) the client uses ESMTP (EHLO
+instead of HELO) and 2) with "smtpd_delay_reject = yes" (the
+default).  The use of reject_unauth_pipelining in the other
+restriction contexts is therefore not recommended.
 .IP "\fBreject\fR"
 Reject the request. This restriction is useful at the end of
 a restriction list, to make the default policy explicit.  The
index ccf72e1f067715dd1bbe1ed548ed14d6acd65fbb..d780e8a14e41f523b44f8500606e9995baa897ab 100755 (executable)
@@ -298,6 +298,7 @@ while (<>) {
     s;\bsetgid_group\b;<a href="postconf.5.html#setgid_group">$&</a>;g;
 
     s;\bsession_cache_service\b;<a href="postconf.5.html#session_cache_service">$&</a>;g;
+    s;\bsession_cache_status_update_time\b;<a href="postconf.5.html#session_cache_status_update_time">$&</a>;g;
     s;\bsession_cache_ttl_limit\b;<a href="postconf.5.html#session_cache_ttl_limit">$&</a>;g;
 
     s;\bshow_user_unknown_table_name\b;<a href="postconf.5.html#show_user_unknown_table_name">$&</a>;g;
index bba86891a5f5b2ca839c792576dc735ad2788963..9ba1d3015a74e875a1f5b6184e2f37f49371b08c 100644 (file)
 #      rule set \fBS3\fR, if you like.  This is controlled with
 #      the \fBcanonical_classes\fR parameter.
 #
-#      The \fBcanonical\fR mapping affects both message header addresses
-#      (i.e. addresses that appear inside messages) and message envelope
-#      addresses (for example, the addresses that are used in SMTP protocol
-#      commands). Think Sendmail rule set \fBS3\fR, if you like.
-#
 #      Typically, one would use the \fBcanonical\fR table to replace login
 #      names by \fIFirstname.Lastname\fR, or to clean up addresses produced
 #      by legacy mail systems.
index 88cdf51344df49a1ba21610bdb9330ea27b00ff5..49994026b6aae524b4472d353e4be3ec914a6373 100644 (file)
@@ -3142,10 +3142,10 @@ optional address extension.
 address extension.
 
 <li> Look up the "user+extension" address local part when the
-recipient domain equals $myorigin, $mydestination, $inet_interfaces
+sender domain equals $myorigin, $mydestination, $inet_interfaces
 or $proxy_interfaces.
 
-<li> Look up the "user" address local part when the recipient domain
+<li> Look up the "user" address local part when the sender domain
 equals $myorigin, $mydestination, $inet_interfaces or $proxy_interfaces.
 
 <li> Look up the "@domain.tld" part.
@@ -4124,18 +4124,27 @@ a restriction list, to make the default policy explicit.</dd>
 <dd>Reject the request when the envelope sender is the null address,
 and the message has multiple envelope recipients. Although this
 usage is technically allowed, it seems to have no legitimate
-application. <br> The multi_recipient_bounce_reject_code parameter
-specifies the response code for rejected requests (default: 550).
-This feature is available in Postfix 2.1 and later. </dd>
+application. <br> NOTE: this restriction can only work reliably
+when used in smtpd_data_restrictions, because the total number of
+recipients is not known at an earlier stage of the SMTP conversation.
+Use at the RCPT stage will only reject the second etc.  recipient.
+<br>
+The multi_recipient_bounce_reject_code parameter specifies the
+response code for rejected requests (default:  550).  This feature
+is available in Postfix 2.1 and later. </dd>
 
 <dt><b><a name="reject_unauth_pipelining">reject_unauth_pipelining</a></b></dt>
 
 <dd>Reject the request when the client sends SMTP commands ahead
 of time where it is not allowed, or when the client sends SMTP
 commands ahead of time without knowing that Postfix actually supports
-SMTP command pipelining. This stops mail from bulk mail software
-that improperly uses SMTP command pipelining in order to speed up
-deliveries.</dd>
+ESMTP command pipelining. This stops mail from bulk mail software
+that improperly uses ESMTP command pipelining in order to speed up
+deliveries. <br> NOTE: reject_unauth_pipelining is not useful
+outside smtpd_data_restrictions when 1) the client uses ESMTP (EHLO
+instead of HELO) and 2) with "smtpd_delay_reject = yes" (the
+default).  The use of reject_unauth_pipelining in the other
+restriction contexts is therefore not recommended.  </dd>
 
 <dt><b><a name="reject">reject</a></b></dt>
 
index f5afe618b9b3c2bede363abb9f94108807048069..205d2e45360701c734e6920c96f0870b082a9591 100644 (file)
@@ -345,12 +345,10 @@ BOUNCE_INFO *bounce_mail_one_init(const char *queue_name,
      * Initialize the bounce_info structure. Forge a logfile record for just
      * one recipient.
      */
-#define REALLY_BOUNCE  1
-
     log_handle = bounce_log_forge(orig_recipient, recipient, offset, dsn_status,
                                  dsn_action, why);
     bounce_info = bounce_mail_alloc("none", queue_name, queue_id,
-                                   encoding, REALLY_BOUNCE, log_handle);
+                                   encoding, BOUNCE_MSG_FAIL, log_handle);
     return (bounce_info);
 }
 
index 9ca267e3927792ccfae911531d0c580d326c9267..03e8adda8219d45e3639834024f1ae8f8acdfe4a 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change the patchlevel and the release date. Snapshots change the
   * release date only.
   */
-#define MAIL_RELEASE_DATE      "20040829"
+#define MAIL_RELEASE_DATE      "20040917"
 #define MAIL_VERSION_NUMBER    "2.2"
 
 #define VAR_MAIL_VERSION       "mail_version"
index 3a913c7320d42f136cb81e1d81cab1f885e8873a..61347047bb336df7b5d9513d675aeb7358391c40 100644 (file)
@@ -6,6 +6,18 @@
 /* SYNOPSIS
 /*     #include <scache.h>
 /* DESCRIPTION
+/*     typedef struct {
+/* .in +4
+/*             int     dest_count;
+/*             int     endp_count;
+/*             int     sess_count;
+/* .in -4
+/*     } SCACHE_SIZE;
+/*
+/*     unsigned scache_size(scache, size)
+/*     SCACHE  *scache;
+/*     SCACHE_SIZE *size;
+/*
 /*     void    scache_free(scache)
 /*     SCACHE  *scache;
 /*
@@ -51,6 +63,9 @@
 /*     endpoints, and one physical endpoint may have multiple
 /*     sessions.
 /*
+/*     scache_size() returns the number of logical destination
+/*     names, physical endpoint addresses, and cached sessions.
+/*
 /*     scache_free() destroys the specified session cache.
 /*
 /*     scache_save_endp() stores an open session under the specified
index c00dd6d6b6b054695a4adc48a5657138ddb57286..1670546c5a61a89da19d189bbedb465a80fc361b 100644 (file)
@@ -17,6 +17,7 @@
 #include <vstring.h>
 
 typedef struct SCACHE SCACHE;
+typedef struct SCACHE_SIZE SCACHE_SIZE;
 
  /*
   * In order to cache a session, we specify:
@@ -85,6 +86,16 @@ typedef int (*SCACHE_FIND_ENDP_FN) (SCACHE *, const char *, VSTRING *);
 typedef void (*SCACHE_SAVE_DEST_FN) (SCACHE *, int, const char *, const char *, const char *);
 typedef int (*SCACHE_FIND_DEST_FN) (SCACHE *, const char *, VSTRING *, VSTRING *);
 
+ /*
+  * Session cache statistics. These are the actual numbers at a specific
+  * point in time.
+  */
+struct SCACHE_SIZE {
+    int     dest_count;                        /* Nr of destination names */
+    int     endp_count;                        /* Nr of endpoint adresses */
+    int     sess_count;                        /* Nr of cached sessions */
+};
+
  /*
   * Generic session cache object. Actual session cache objects are derived
   * types with some additional, cache dependent, private information.
@@ -94,6 +105,7 @@ struct SCACHE {
     SCACHE_FIND_ENDP_FN find_endp;
     SCACHE_SAVE_DEST_FN save_dest;
     SCACHE_FIND_DEST_FN find_dest;
+    void    (*size) (struct SCACHE *, SCACHE_SIZE *);
     void    (*free) (struct SCACHE *);
 };
 
@@ -109,6 +121,7 @@ extern SCACHE *scache_multi_create(void);
     (scache)->save_dest((scache), (ttl), (dest_label), (dest_prop), (endp_label))
 #define scache_find_dest(scache, dest_label, dest_prop, endp_prop) \
     (scache)->find_dest((scache), (dest_label), (dest_prop), (endp_prop))
+#define scache_size(scache, stats) (scache)->size((scache), (stats))
 #define scache_free(scache) (scache)->free(scache)
 
  /*
index 6bb233daa39bcf9167ce84fdcf2a8fbad03ba428..3838294d7f84407b90f0a540bea00946815f5aa8 100644 (file)
@@ -306,6 +306,16 @@ static int scache_clnt_find_dest(SCACHE *scache, const char *dest_label,
     return (-1);
 }
 
+/* scache_clnt_size - dummy */
+
+static void scache_clnt_size(SCACHE *scache, SCACHE_SIZE *size)
+{
+    /* XXX Crap in a hurry. */
+    size->dest_count = 0;
+    size->endp_count = 0;
+    size->sess_count = 0;
+}
+
 /* scache_clnt_free - destroy cache */
 
 static void scache_clnt_free(SCACHE *scache)
@@ -329,6 +339,7 @@ SCACHE *scache_clnt_create(const char *server, int idle_limit, int ttl_limit)
     sp->scache->find_endp = scache_clnt_find_endp;
     sp->scache->save_dest = scache_clnt_save_dest;
     sp->scache->find_dest = scache_clnt_find_dest;
+    sp->scache->size = scache_clnt_size;
     sp->scache->free = scache_clnt_free;
 
     sp->clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE, server,
index 1053fd992b604f3155f7caec1a222db9d032fb11..4e82e8e2b3e383b12e31eded89004fe6e88c1fb6 100644 (file)
@@ -75,18 +75,18 @@ typedef struct {
     SCACHE  scache[1];                 /* super-class */
     HTABLE *dest_cache;                        /* destination->endpoint bindings */
     HTABLE *endp_cache;                        /* endpoint->session bindings */
+    int     sess_count;                        /* number of cached sessions */
 } SCACHE_MULTI;
 
  /*
-  * Storage for a destination or endpoint list head. The list head has
-  * references to its own hash table entry, so that we can remove a list when
-  * it becomes empty. List items are stored in a circular list under the list
-  * head.
+  * Storage for a destination or endpoint list head. Each list head knows its
+  * own hash table entry name, so that we can remove the list when it becomes
+  * empty. List items are stored in a circular list under the list head.
   */
 typedef struct {
     RING    ring[1];                   /* circular list linkage */
-    HTABLE *parent_table;              /* parent info */
-    char   *parent_key;                        /* parent info */
+    char   *parent_key;                        /* parent linkage: hash table */
+    SCACHE_MULTI *cache;               /* parent linkage: cache */
 } SCACHE_MULTI_HEAD;
 
 #define RING_TO_MULTI_HEAD(p) RING_TO_APPL((p), SCACHE_MULTI_HEAD, ring)
@@ -97,6 +97,7 @@ typedef struct {
   */
 typedef struct {
     RING    ring[1];                   /* circular list linkage */
+    SCACHE_MULTI_HEAD *head;           /* parent linkage: list head */
     char   *endp_label;                        /* endpoint name */
     char   *dest_prop;                 /* binding properties */
 } SCACHE_MULTI_DEST;
@@ -111,6 +112,7 @@ static void scache_multi_expire_dest(int, char *);
   */
 typedef struct {
     RING    ring[1];                   /* circular list linkage */
+    SCACHE_MULTI_HEAD *head;           /* parent linkage: list head */
     int     fd;                                /* cached session */
     char   *endp_prop;                 /* binding properties */
 } SCACHE_MULTI_ENDP;
@@ -149,12 +151,11 @@ static void scache_multi_drop_endp(SCACHE_MULTI_ENDP *endp, int direction)
      * the list becomes empty. Otherwise, remove the endpoint->session
      * binding from the list.
      */
-    if (direction == BOTTOM_UP
-       && ring_pred(endp->ring) == ring_succ(endp->ring)) {
-       head = RING_TO_MULTI_HEAD(ring_pred(endp->ring));
-       htable_delete(head->parent_table, head->parent_key, myfree);
-    } else
-       ring_detach(endp->ring);
+    ring_detach(endp->ring);
+    head = endp->head;
+    head->cache->sess_count--;
+    if (direction == BOTTOM_UP && ring_pred(head->ring) == head->ring)
+       htable_delete(head->cache->endp_cache, head->parent_key, myfree);
 
     /*
      * Destroy the endpoint->session binding.
@@ -215,9 +216,9 @@ static void scache_multi_save_endp(SCACHE *scache, int ttl,
         htable_find(sp->endp_cache, endp_label)) == 0) {
        head = (SCACHE_MULTI_HEAD *) mymalloc(sizeof(*head));
        ring_init(head->ring);
-       head->parent_table = sp->endp_cache;
        head->parent_key =
            htable_enter(sp->endp_cache, endp_label, (char *) head)->key;
+       head->cache = sp;
     }
 
     /*
@@ -225,9 +226,11 @@ static void scache_multi_save_endp(SCACHE *scache, int ttl,
      * duplicate, because each session must have a different file descriptor.
      */
     endp = (SCACHE_MULTI_ENDP *) mymalloc(sizeof(*endp));
+    endp->head = head;
     endp->fd = fd;
     endp->endp_prop = mystrdup(endp_prop);
     ring_prepend(head->ring, endp->ring);
+    sp->sess_count++;
 
     /*
      * Make sure this binding will go away eventually.
@@ -303,12 +306,10 @@ static void scache_multi_drop_dest(SCACHE_MULTI_DEST *dest, int direction)
      * the list becomes empty. Otherwise, remove the destination->endpoint
      * binding from the list.
      */
-    if (direction == BOTTOM_UP
-       && ring_pred(dest->ring) == ring_succ(dest->ring)) {
-       head = RING_TO_MULTI_HEAD(ring_pred(dest->ring));
-       htable_delete(head->parent_table, head->parent_key, myfree);
-    } else
-       ring_detach(dest->ring);
+    ring_detach(dest->ring);
+    head = dest->head;
+    if (direction == BOTTOM_UP && ring_pred(head->ring) == head->ring)
+       htable_delete(head->cache->dest_cache, head->parent_key, myfree);
 
     /*
      * Destroy the destination->endpoint binding.
@@ -371,9 +372,9 @@ static void scache_multi_save_dest(SCACHE *scache, int ttl,
         htable_find(sp->dest_cache, dest_label)) == 0) {
        head = (SCACHE_MULTI_HEAD *) mymalloc(sizeof(*head));
        ring_init(head->ring);
-       head->parent_table = sp->dest_cache;
        head->parent_key =
            htable_enter(sp->dest_cache, dest_label, (char *) head)->key;
+       head->cache = sp;
     }
 
     /*
@@ -390,6 +391,7 @@ static void scache_multi_save_dest(SCACHE *scache, int ttl,
     }
     if (refresh == 0) {
        dest = (SCACHE_MULTI_DEST *) mymalloc(sizeof(*dest));
+       dest->head = head;
        dest->endp_label = mystrdup(endp_label);
        dest->dest_prop = mystrdup(dest_prop);
        ring_prepend(head->ring, dest->ring);
@@ -446,7 +448,18 @@ static int scache_multi_find_dest(SCACHE *scache, const char *dest_label,
     return (-1);
 }
 
-/* scache_multi_free - destroy single-element cache object */
+/* scache_multi_size - size of multi-element cache object */
+
+static void scache_multi_size(SCACHE *scache, SCACHE_SIZE *size)
+{
+    SCACHE_MULTI *sp = (SCACHE_MULTI *) scache;
+
+    size->dest_count = sp->dest_cache->used;
+    size->endp_count = sp->endp_cache->used;
+    size->sess_count = sp->sess_count;
+}
+
+/* scache_multi_free - destroy multi-element cache object */
 
 static void scache_multi_free(SCACHE *scache)
 {
@@ -468,10 +481,12 @@ SCACHE *scache_multi_create(void)
     sp->scache->find_endp = scache_multi_find_endp;
     sp->scache->save_dest = scache_multi_save_dest;
     sp->scache->find_dest = scache_multi_find_dest;
+    sp->scache->size = scache_multi_size;
     sp->scache->free = scache_multi_free;
 
     sp->dest_cache = htable_create(1);
     sp->endp_cache = htable_create(1);
+    sp->sess_count = 0;
 
     return (sp->scache);
 }
index 8bf63cb54da2329345af5a9fb313cf7af55811c8..972d45cfba3dabd4fecdb526895eda9d183babb9 100644 (file)
@@ -6,96 +6,47 @@
 >>> # Destination name space collision test
 >>> 
 >>> save_dest 2 a_dest a_prop b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop endp_label=b_endp
 >>> sleep 1
 >>> save_dest 2 a_dest a_prop b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop endp_label=b_endp (refreshed)
 >>> sleep 1
 >>> save_dest 2 a_dest a_prop b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop endp_label=b_endp (refreshed)
 >>> sleep 2
-unknown: scache_multi_drop_dest: dest_prop=a_prop endp_label=b_endp
 >>> 
 >>> # Another destination name space collision test
 >>> 
 >>> save_dest 2 a_dest a_prop b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop endp_label=b_endp
 >>> sleep 1
 >>> save_dest 2 a_dest a_prop2 b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop2 endp_label=b_endp
 >>> sleep 1
-unknown: scache_multi_drop_dest: dest_prop=a_prop endp_label=b_endp
 >>> save_dest 2 a_dest a_prop2 b_endp2
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop2 endp_label=b_endp2
 >>> sleep 2
-unknown: scache_multi_drop_dest: dest_prop=a_prop2 endp_label=b_endp
-unknown: scache_multi_drop_dest: dest_prop=a_prop2 endp_label=b_endp2
 >>> 
 >>> # Endpoint name space collision test
 >>> 
 >>> save_endp 2 b_endp b_prop 12
-unknown: scache_multi_save_endp: endp_label=b_endp -> endp_prop=b_prop fd=12
 >>> save_endp 2 b_endp b_prop 13
-unknown: scache_multi_save_endp: endp_label=b_endp -> endp_prop=b_prop fd=13
 >>> sleep 3
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=12
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=13
 >>> 
 >>> # Combined destiation and endpoint collision test with lookup
 >>> 
 >>> save_dest 2 a_dest a_prop b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop endp_label=b_endp
 >>> save_dest 2 a_dest a_prop2 b_endp
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop2 endp_label=b_endp
 >>> save_dest 2 a_dest a_prop2 b_endp2
-unknown: scache_multi_save_dest: dest_label=a_dest -> dest_prop=a_prop2 endp_label=b_endp2
 >>> save_endp 2 b_endp b_prop 12
-unknown: scache_multi_save_endp: endp_label=b_endp -> endp_prop=b_prop fd=12
 >>> save_endp 2 b_endp b_prop 13
-unknown: scache_multi_save_endp: endp_label=b_endp -> endp_prop=b_prop fd=13
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: found: endp_label=b_endp -> endp_prop=b_prop fd=12
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=-1
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: found: endp_label=b_endp -> endp_prop=b_prop fd=13
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=-1
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp2
-unknown: scache_multi_find_dest: not found: dest_label=a_dest
 >>> 
 >>> # Another combined destiation and endpoint collision test with lookup
 >>> 
 >>> save_endp 2 b_endp2 b_prop 12
-unknown: scache_multi_save_endp: endp_label=b_endp2 -> endp_prop=b_prop fd=12
 >>> save_endp 2 b_endp2 b_prop 13
-unknown: scache_multi_save_endp: endp_label=b_endp2 -> endp_prop=b_prop fd=13
 >>> save_endp 2 b_endp2 b_prop 14
-unknown: scache_multi_save_endp: endp_label=b_endp2 -> endp_prop=b_prop fd=14
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: found: endp_label=b_endp2 -> endp_prop=b_prop fd=12
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=-1
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: found: endp_label=b_endp2 -> endp_prop=b_prop fd=13
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=-1
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: found: endp_label=b_endp2 -> endp_prop=b_prop fd=14
-unknown: scache_multi_drop_endp: endp_prop=b_prop fd=-1
 >>> find_dest a_dest
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp
-unknown: scache_multi_find_endp: no endpoint cache: endp_label=b_endp2
-unknown: scache_multi_find_dest: not found: dest_label=a_dest
 >>> 
 >>> # Let the exit handler clean up the destiation->endpoint bindings.
 >>> 
-unknown: scache_multi_drop_dest: dest_prop=a_prop endp_label=b_endp
-unknown: scache_multi_drop_dest: dest_prop=a_prop2 endp_label=b_endp
-unknown: scache_multi_drop_dest: dest_prop=a_prop2 endp_label=b_endp2
index c6ad17e4a049921d8792687fcba1e90cf013cf99..28ed333db368cac7573fec9b8f9dac288e381745 100644 (file)
@@ -257,6 +257,17 @@ static int scache_single_find_dest(SCACHE *scache, const char *dest_label,
     return (-1);
 }
 
+/* scache_single_size - size of single-element cache :-) */
+
+static void scache_single_size(SCACHE *scache, SCACHE_SIZE *size)
+{
+    SCACHE_SINGLE *sp = (SCACHE_SINGLE *) scache;
+
+    size->dest_count = (!SCACHE_SINGLE_DEST_BUSY(sp) ? 0 : 1);
+    size->endp_count = (!SCACHE_SINGLE_ENDP_BUSY(sp) ? 0 : 1);
+    size->sess_count = (sp->endp.fd < 0 ? 0 : 1);
+}
+
 /* scache_single_free - destroy single-element cache object */
 
 static void scache_single_free(SCACHE *scache)
@@ -285,6 +296,7 @@ SCACHE *scache_single_create(void)
     sp->scache->find_endp = scache_single_find_endp;
     sp->scache->save_dest = scache_single_save_dest;
     sp->scache->find_dest = scache_single_find_dest;
+    sp->scache->size = scache_single_size;
     sp->scache->free = scache_single_free;
 
     sp->endp.endp_label = vstring_alloc(10);
index 8ca7858eaeccb56ce8e72d86355212663d504cd1..85f7d81649418ff9d6f2b991b264577fc2739026 100644 (file)
@@ -186,8 +186,11 @@ static SCACHE *scache;
   */
 static int scache_dest_hits;
 static int scache_dest_miss;
+static int scache_dest_count;
 static int scache_endp_hits;
 static int scache_endp_miss;
+static int scache_endp_count;
+static int scache_sess_count;
 time_t  scache_start_time;
 
  /*
@@ -203,6 +206,7 @@ static void scache_save_endp_service(VSTREAM *client_stream)
     const char *myname = "scache_save_endp_service";
     int     ttl;
     int     fd;
+    SCACHE_SIZE size;
 
     if (attr_scan(client_stream,
                  ATTR_FLAG_STRICT,
@@ -239,6 +243,11 @@ static void scache_save_endp_service(VSTREAM *client_stream)
        attr_print(client_stream, ATTR_FLAG_NONE,
                   ATTR_TYPE_NUM, MAIL_ATTR_STATUS, SCACHE_STAT_OK,
                   ATTR_TYPE_END);
+       scache_size(scache, &size);
+       if (size.endp_count > scache_endp_count)
+           scache_endp_count = size.endp_count;
+       if (size.sess_count > scache_sess_count)
+           scache_sess_count = size.sess_count;
        return;
     }
 }
@@ -294,6 +303,7 @@ static void scache_save_dest_service(VSTREAM *client_stream)
 {
     const char *myname = "scache_save_dest_service";
     int     ttl;
+    SCACHE_SIZE size;
 
     if (attr_scan(client_stream,
                  ATTR_FLAG_STRICT,
@@ -316,6 +326,12 @@ static void scache_save_dest_service(VSTREAM *client_stream)
        attr_print(client_stream, ATTR_FLAG_NONE,
                   ATTR_TYPE_NUM, MAIL_ATTR_STATUS, SCACHE_STAT_OK,
                   ATTR_TYPE_END);
+       scache_size(scache, &size);
+       if (size.dest_count > scache_dest_count)
+           scache_dest_count = size.dest_count;
+       if (size.endp_count > scache_endp_count)
+           scache_endp_count = size.endp_count;
+       return;
        return;
     }
 }
@@ -414,7 +430,9 @@ static void scache_service(VSTREAM *client_stream, char *unused_service,
 static void scache_status_dump(char *unused_name, char **unused_argv)
 {
     if (scache_dest_hits || scache_dest_miss
-       || scache_endp_hits || scache_endp_miss)
+       || scache_endp_hits || scache_endp_miss
+       || scache_dest_count || scache_endp_count
+       || scache_sess_count)
        msg_info("statistics: start interval %.15s",
                 ctime(&scache_start_time) + 4);
 
@@ -432,6 +450,13 @@ static void scache_status_dump(char *unused_name, char **unused_argv)
                 / (scache_endp_hits + scache_endp_miss));
        scache_endp_hits = scache_endp_miss = 0;
     }
+    if (scache_dest_count || scache_endp_count || scache_sess_count) {
+       msg_info("statistics: max simultaneous domains=%d addresses=%d sessions=%d",
+                scache_dest_count, scache_endp_count, scache_sess_count);
+       scache_dest_count = 0;
+       scache_endp_count = 0;
+       scache_sess_count = 0;
+    }
     scache_start_time = event_time();
 }
 
index 705e782ee8fec6a662e77c84425bf38b0542ad5e..f644ded9400b9218dc9fb90749825259e7e08d7e 100644 (file)
@@ -151,7 +151,7 @@ void    smtp_save_session(SMTP_STATE *state)
                         STR(state->dest_prop), STR(state->endp_label));
 
     /*
-     * Save every good sessions under its physical endpoint address.
+     * Save every good session under its physical endpoint address.
      */
     scache_save_endp(smtp_scache, var_smtp_cache_conn, STR(state->endp_label),
                     STR(state->endp_prop), fd);
index e56739801ddafaf6bcd7b3dba8fd1aec31973d46..37a3598bb415f9f226dee6b085164317e3e7861b 100644 (file)
@@ -911,6 +911,8 @@ extern int h_errno;
  */
 #include <cpio.h>
 #define S_ISSOCK(mode) (((mode) & (S_IFMT)) == (C_ISSOCK))
+#define CANT_USE_SEND_RECV_MSG
+#define DEF_SMTP_CACHE_DEMAND  0
 #endif
 
  /*