]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.10-20120908
authorWietse Venema <wietse@porcupine.org>
Sat, 8 Sep 2012 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:38:16 +0000 (06:38 +0000)
postfix/.indent.pro
postfix/HISTORY
postfix/conf/header_checks
postfix/html/header_checks.5.html
postfix/man/man5/header_checks.5
postfix/proto/header_checks
postfix/src/global/mail_version.h
postfix/src/sendmail/sendmail.c
postfix/src/util/Makefile.in
postfix/src/util/dict_sockmap.c

index df478eb1f5c91b305f0353d0a3b9d608cf858d4c..d79ef9582f484b7cded4ac5250fc7cba5b5556c0 100644 (file)
@@ -99,6 +99,7 @@
 -TDICT_REGEXP_RULE
 -TDICT_SDBM
 -TDICT_SOCKMAP
+-TDICT_SOCKMAP_REFC_HANDLE
 -TDICT_SQLITE
 -TDICT_STACK
 -TDICT_SURROGATE
index 43d5a7943ebe27a98c4eddc445713a91994a569f..0f30ecef885b4127d919e118985766f5b0def13f 100644 (file)
@@ -17929,3 +17929,15 @@ Apologies for any names omitted.
        Documentation: updated TUNING_README with new pointers to
        the STRESS_README and POSTSCREEN_README documents. Miscellaneous
        documentation clarifications based on postfix-users discussions.
+
+20120903
+
+       Bugfix (introduced 20120317): the socketmap client should
+       not share unrelated client endpoint handles. File:
+       util/dict_sockmap.c.
+
+20120907
+
+       Cleanup (for change 20120824): the DSN RET attribute should
+       not be stored once per recipient. It is a message property
+       just like DSN ENVID.  File: sendmail/sendmail.c.
index f10e2dfaffe8c2e806f48053ef4eb33432b64c49..490e214c7252cb350217c75e07f9a850c121373b 100644 (file)
 #        This  document  assumes  that header and body_checks rules
 #        are specified in the form of  Postfix  regular  expression
 #        lookup  tables.  Usually  the best performance is obtained
-#        with pcre (Perl Compatible Regular Expression) tables, but
-#        the  slower  regexp (POSIX regular expressions) support is
-#        more widely available.  Use the command "postconf  -m"  to
-#        find  out what lookup table types your Postfix system sup-
-#        ports.
+#        with pcre (Perl Compatible Regular Expression) tables. The
+#        regexp  (POSIX  regular  expressions)  tables  are usually
+#        slower, but more widely available.  Use the command "post-
+#        conf  -m" to find out what lookup table types your Postfix
+#        system supports.
 # 
 #        The general format of Postfix regular expression tables is
 #        given  below.   For  a  discussion  of specific pattern or
index 9705e12c7faa8369723420a627d39d1ed03aa2a7..c1d2fe860c58c3607f1075f8121e652f2c75e5d8 100644 (file)
@@ -114,11 +114,11 @@ HEADER_CHECKS(5)                                              HEADER_CHECKS(5)
        This  document  assumes  that header and <a href="postconf.5.html#body_checks">body_checks</a> rules
        are specified in the form of  Postfix  regular  expression
        lookup  tables.  Usually  the best performance is obtained
-       with <b>pcre</b> (Perl Compatible Regular Expression) tables, but
-       the  slower  <b>regexp</b> (POSIX regular expressions) support is
-       more widely available.  Use the command "<b>postconf  -m</b>"  to
-       find  out what lookup table types your Postfix system sup-
-       ports.
+       with <b>pcre</b> (Perl Compatible Regular Expression) tables. The
+       <b>regexp</b>  (POSIX  regular  expressions)  tables  are usually
+       slower, but more widely available.  Use the command "<b>post-</b>
+       <b>conf  -m</b>" to find out what lookup table types your Postfix
+       system supports.
 
        The general format of Postfix regular expression tables is
        given  below.   For  a  discussion  of specific pattern or
index 5ce90a80de3d04a3d477f70a9463c15fbd27c50b..10cd89a00dabb48dbf63cfd72a351830f5a2e339 100644 (file)
@@ -117,8 +117,9 @@ insensitive.
 This document assumes that header and body_checks rules are specified
 in the form of Postfix regular expression lookup tables. Usually the
 best performance is obtained with \fBpcre\fR (Perl Compatible Regular
-Expression) tables, but the slower \fBregexp\fR (POSIX regular
-expressions) support is more widely available.
+Expression) tables. The \fBregexp\fR (POSIX regular
+expressions) tables are usually slower, but more widely
+available.
 Use the command "\fBpostconf -m\fR" to find out what lookup table
 types your Postfix system supports.
 
index bf1cb0007dd2544064dbdb4ce487bb653cd1bf0f..b797e6b5ef7d3e41123f1e0a93b1972a6ce04bd7 100644 (file)
 #      This document assumes that header and body_checks rules are specified
 #      in the form of Postfix regular expression lookup tables. Usually the
 #      best performance is obtained with \fBpcre\fR (Perl Compatible Regular
-#      Expression) tables, but the slower \fBregexp\fR (POSIX regular
-#      expressions) support is more widely available.
+#      Expression) tables. The \fBregexp\fR (POSIX regular
+#      expressions) tables are usually slower, but more widely
+#      available.
 #      Use the command "\fBpostconf -m\fR" to find out what lookup table
 #      types your Postfix system supports.
 #
index 6d55f5da87dc212d9f34644f377c835a7dd0ffa2..ac51d149a78c82971c95d156b2395ec362530dab 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20120902"
+#define MAIL_RELEASE_DATE      "20120908"
 #define MAIL_VERSION_NUMBER    "2.10"
 
 #ifdef SNAPSHOT
index c7394cd67029cb53f5665f5b61992392585b8a65..88a7b67ec0da6bf48698601cd60f7999b11bac7c 100644 (file)
@@ -612,7 +612,7 @@ static void output_header(void *context, int header_class,
 /* enqueue - post one message */
 
 static void enqueue(const int flags, const char *encoding,
-                        const char *dsn_envid, int dsn_notify, int dsn_ret,
+                        const char *dsn_envid, int dsn_ret, int dsn_notify,
                            const char *rewrite_context, const char *sender,
                            const char *full_name, char **recipients)
 {
@@ -726,6 +726,9 @@ static void enqueue(const int flags, const char *encoding,
     if (dsn_envid)
        rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s",
                    MAIL_ATTR_DSN_ENVID, dsn_envid);
+    if (dsn_ret)
+       rec_fprintf(dst, REC_TYPE_ATTR, "%s=%d",
+                   MAIL_ATTR_DSN_RET, dsn_ret);
     rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s",
                MAIL_ATTR_RWR_CONTEXT, rewrite_context);
     if (full_name || (full_name = fullname()) != 0)
@@ -751,9 +754,6 @@ static void enqueue(const int flags, const char *encoding,
                    if (dsn_notify)
                        rec_fprintf(dst, REC_TYPE_ATTR, "%s=%d",
                                    MAIL_ATTR_DSN_NOTIFY, dsn_notify);
-                   if (dsn_ret)
-                       rec_fprintf(dst, REC_TYPE_ATTR, "%s=%d",
-                                   MAIL_ATTR_DSN_RET, dsn_ret);
                    if (REC_PUT_BUF(dst, REC_TYPE_RCPT, buf) < 0)
                        msg_fatal_status(EX_TEMPFAIL,
                                    "%s(%ld): error writing queue file: %m",
@@ -893,10 +893,6 @@ static void enqueue(const int flags, const char *encoding,
            if (dsn_notify)
                rec_fprintf(dst, REC_TYPE_ATTR, "%s=%d",
                            MAIL_ATTR_DSN_NOTIFY, dsn_notify);
-           if (dsn_ret)
-               rec_fprintf(dst, REC_TYPE_ATTR, "%s=%d",
-                           MAIL_ATTR_DSN_RET, dsn_ret);
-
            if (rec_put(dst, REC_TYPE_RCPT, *cpp, strlen(*cpp)) < 0)
                msg_fatal_status(EX_TEMPFAIL,
                                 "%s(%ld): error writing queue file: %m",
@@ -1354,7 +1350,7 @@ int     main(int argc, char **argv)
            mail_run_replace(var_command_dir, ext_argv->argv);
            /* NOTREACHED */
        } else {
-           enqueue(flags, encoding, dsn_envid, dsn_notify, dsn_ret,
+           enqueue(flags, encoding, dsn_envid, dsn_ret, dsn_notify,
                    rewrite_context, sender, full_name, argv + OPTIND);
            exit(0);
            /* NOTREACHED */
index 59bbc35875f9b9bbf68f15f1643b104967e61135..48990a635c839c34f71a19b9cb822c3f22597766 100644 (file)
@@ -1080,6 +1080,7 @@ dict_sockmap.o: auto_clnt.h
 dict_sockmap.o: dict.h
 dict_sockmap.o: dict_sockmap.c
 dict_sockmap.o: dict_sockmap.h
+dict_sockmap.o: htable.h
 dict_sockmap.o: msg.h
 dict_sockmap.o: mymalloc.h
 dict_sockmap.o: netstring.h
index b403939397ab84ffe1acc7b2ffe6c70ddf3dba1a..f177066bd0280ed287e74d749eeaf6ebe220674e 100644 (file)
 /*     Postfix socketmap names have the form inet:host:port:socketmap-name
 /*     or unix:pathname:socketmap-name, where socketmap-name
 /*     specifies the socketmap name that the socketmap server uses.
+/*
+/*     To test this module, build the netstring and dict_open test
+/*     programs. Run "./netstring nc -l portnumber" as the server,
+/*     and "./dict_open socketmap:127.0.0.1:portnumber:socketmapname"
+/*     as the client.
 /* PROTOCOL
 /* .ad
 /* .fi
@@ -89,6 +94,7 @@
 #include <netstring.h>
 #include <split_at.h>
 #include <stringops.h>
+#include <htable.h>
 #include <dict_sockmap.h>
 
  /*
@@ -98,6 +104,7 @@ typedef struct {
     DICT    dict;                      /* parent class */
     char   *sockmap_name;              /* on-the-wire socketmap name */
     VSTRING *rdwr_buf;                 /* read/write buffer */
+    HTABLE_INFO *client_info;          /* shared endpoint name and handle */
 } DICT_SOCKMAP;
 
  /*
@@ -111,13 +118,29 @@ typedef struct {
  /*
   * Class variables.
   */
-static AUTO_CLNT *dict_sockmap_clnt;   /* auto_clnt handle */
-static int dict_sockmap_refcount;      /* handle reference count */
 static int dict_sockmap_timeout = DICT_SOCKMAP_DEF_TIMEOUT;
 static int dict_sockmap_max_reply = DICT_SOCKMAP_DEF_MAX_REPLY;
 static int dict_sockmap_max_idle = DICT_SOCKMAP_DEF_MAX_IDLE;
 static int dict_sockmap_max_ttl = DICT_SOCKMAP_DEF_MAX_TTL;
 
+ /*
+  * The client handle is shared between socketmap instances that have the
+  * same inet:host:port or unix:pathame information. This could be factored
+  * out as a general module for reference-counted handles of any kind.
+  */
+static HTABLE *dict_sockmap_handles;   /* shared handles */
+
+typedef struct {
+    AUTO_CLNT *client_handle;          /* the client handle */
+    int     refcount;                  /* the reference count */
+} DICT_SOCKMAP_REFC_HANDLE;
+
+#define DICT_SOCKMAP_RH_NAME(ht)       (ht)->key
+#define DICT_SOCKMAP_RH_HANDLE(ht) \
+       ((DICT_SOCKMAP_REFC_HANDLE *) (ht)->value)->client_handle
+#define DICT_SOCKMAP_RH_REFCOUNT(ht) \
+       ((DICT_SOCKMAP_REFC_HANDLE *) (ht)->value)->refcount
+
  /*
   * Socketmap protocol elements.
   */
@@ -139,6 +162,7 @@ static const char *dict_sockmap_lookup(DICT *dict, const char *key)
 {
     const char *myname = "dict_sockmap_lookup";
     DICT_SOCKMAP *dp = (DICT_SOCKMAP *) dict;
+    AUTO_CLNT *sockmap_clnt = DICT_SOCKMAP_RH_HANDLE(dp->client_info);
     VSTREAM *fp;
     int     netstring_err;
     char   *reply_payload;
@@ -167,7 +191,7 @@ static const char *dict_sockmap_lookup(DICT *dict, const char *key)
        /*
         * Look up the stream.
         */
-       if ((fp = auto_clnt_access(dict_sockmap_clnt)) == 0) {
+       if ((fp = auto_clnt_access(sockmap_clnt)) == 0) {
            msg_warn("table %s:%s lookup error: %m", dict->type, dict->name);
            dict->error = DICT_ERR_RETRY;
            return (0);
@@ -206,7 +230,7 @@ static const char *dict_sockmap_lookup(DICT *dict, const char *key)
             */
            if (except_count == 0 && netstring_err == NETSTRING_ERR_EOF
                && errno != ETIMEDOUT) {
-               auto_clnt_recover(dict_sockmap_clnt);
+               auto_clnt_recover(sockmap_clnt);
                continue;
            }
 
@@ -263,17 +287,21 @@ static const char *dict_sockmap_lookup(DICT *dict, const char *key)
 
 static void dict_sockmap_close(DICT *dict)
 {
+    const char *myname = "dict_sockmap_close";
     DICT_SOCKMAP *dp = (DICT_SOCKMAP *) dict;
 
+    if (dict_sockmap_handles == 0 || dict_sockmap_handles->used == 0)
+       msg_panic("%s: attempt to close a non-existent map", myname);
     vstring_free(dp->rdwr_buf);
     myfree(dp->sockmap_name);
-    if (--dict_sockmap_refcount == 0) {
-       auto_clnt_free(dict_sockmap_clnt);
-       dict_sockmap_clnt = 0;
+    if (--DICT_SOCKMAP_RH_REFCOUNT(dp->client_info) == 0) {
+       auto_clnt_free(DICT_SOCKMAP_RH_HANDLE(dp->client_info));
+       htable_delete(dict_sockmap_handles,
+                     DICT_SOCKMAP_RH_NAME(dp->client_info), myfree);
     }
     if (dict->fold_buf)
        vstring_free(dict->fold_buf);
-    myfree((char *) dp);
+    dict_free(dict);
 }
 
 /* dict_sockmap_open - open socket map */
@@ -283,6 +311,8 @@ DICT   *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
     DICT_SOCKMAP *dp;
     char   *saved_name;
     char   *sockmap;
+    DICT_SOCKMAP_REFC_HANDLE *ref_handle;
+    HTABLE_INFO *client_info;
 
     /*
      * Sanity checks.
@@ -299,7 +329,7 @@ DICT   *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
                               DICT_TYPE_SOCKMAP, mapname));
 
     /*
-     * Split the socketmap name off the Postfix mapname.
+     * Separate the socketmap name from the socketmap server name.
      */
     saved_name = mystrdup(mapname);
     if ((sockmap = split_at_right(saved_name, ':')) == 0)
@@ -309,14 +339,24 @@ DICT   *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
                               DICT_TYPE_SOCKMAP));
 
     /*
-     * Instantiate the shared client handle.
+     * Use one reference-counted client handle for all socketmaps with the
+     * same inet:host:port or unix:pathname information.
      * 
      * XXX Todo: graceful degradation after endpoint syntax error.
      */
-    if (dict_sockmap_refcount == 0)
-       dict_sockmap_clnt = auto_clnt_create(saved_name, dict_sockmap_timeout,
-                              dict_sockmap_max_idle, dict_sockmap_max_ttl);
-    dict_sockmap_refcount += 1;
+    if (dict_sockmap_handles == 0)
+       dict_sockmap_handles = htable_create(1);
+    if ((client_info = htable_locate(dict_sockmap_handles, saved_name)) == 0) {
+       ref_handle = (DICT_SOCKMAP_REFC_HANDLE *) mymalloc(sizeof(*ref_handle));
+       client_info = htable_enter(dict_sockmap_handles,
+                                  saved_name, (char *) ref_handle);
+       /* XXX Late initialization, so we can reuse macros for consistency. */
+       DICT_SOCKMAP_RH_REFCOUNT(client_info) = 1;
+       DICT_SOCKMAP_RH_HANDLE(client_info) =
+           auto_clnt_create(saved_name, dict_sockmap_timeout,
+                            dict_sockmap_max_idle, dict_sockmap_max_ttl);
+    } else
+       DICT_SOCKMAP_RH_REFCOUNT(client_info) += 1;
 
     /*
      * Instantiate a socket map handle.
@@ -324,6 +364,7 @@ DICT   *dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
     dp = (DICT_SOCKMAP *) dict_alloc(DICT_TYPE_SOCKMAP, mapname, sizeof(*dp));
     dp->rdwr_buf = vstring_alloc(100);
     dp->sockmap_name = mystrdup(sockmap);
+    dp->client_info = client_info;
     dp->dict.lookup = dict_sockmap_lookup;
     dp->dict.close = dict_sockmap_close;
     /* Don't look up parent domains or network superblocks. */