]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.8-20101130
authorWietse Venema <wietse@porcupine.org>
Tue, 30 Nov 2010 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:36:43 +0000 (06:36 +0000)
32 files changed:
postfix/HISTORY
postfix/README_FILES/POSTSCREEN_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/POSTSCREEN_README.html
postfix/html/postconf.5.html
postfix/html/postscreen.8.html
postfix/man/man5/postconf.5
postfix/man/man8/postscreen.8
postfix/mantools/postlink
postfix/proto/POSTSCREEN_README.html
postfix/proto/postconf.proto
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/postscreen/Makefile.in
postfix/src/postscreen/postscreen.c
postfix/src/postscreen/postscreen.h
postfix/src/postscreen/postscreen_dnsbl.c
postfix/src/postscreen/postscreen_early.c
postfix/src/postscreen/postscreen_misc.c
postfix/src/postscreen/postscreen_send.c
postfix/src/postscreen/postscreen_smtpd.c
postfix/src/postscreen/postscreen_state.c
postfix/src/postscreen/postscreen_tests.c
postfix/src/util/Makefile.in
postfix/src/util/ip_lmatch.c [deleted file]
postfix/src/util/ip_lmatch.h [deleted file]
postfix/src/util/ip_lmatch.in [deleted file]
postfix/src/util/ip_lmatch.ref [deleted file]
postfix/src/util/ip_match.c
postfix/src/util/ip_match.in
postfix/src/util/ip_match.ref

index 960ad72bd84b8b3def62638942cb6ddea1fab569..793c2aab9fb373465ce4d32f9aeb7b58ad904103 100644 (file)
@@ -16176,3 +16176,21 @@ Apologies for any names omitted.
 
        Cleanup: don't log "blocked using example.com=127.0.0.1",
        just log the domain name. File: smtpd/smtpd_check.c.
+
+20101129
+
+       Cleanup: postscreen_client_connection_count_limit (default:
+       $smtpd_client_connection_count_limit) to limit the number
+       of connections from the same IP address to the postscreen(8)
+       daemon. Files: postscreen/postscreen.c, postscreen/postscreen.h,
+       postscreen/postscreen_state.c.
+
+20101130
+
+       Cleanup: all postscreen(8) logging now reports the client
+       as [address]:port.  This requires an update of tools that
+       process postscreen logging.  Files: postscreen/*.c,
+       proto/POSTSCREEN_README.html.
+
+       Cleanup: polishing recent documentation and code. Files:
+       postscreen/postscreen_dnsbl.c, util/ip_match.c.
index d06b7237c2cdc146cdec27508cb80c62e89b9d05..a03ebe34a7c2f01a7582d4077b82a3f0a7f73d30 100644 (file)
@@ -93,9 +93,10 @@ P\bPe\ber\brm\bma\ban\bne\ben\bnt\bt w\bwh\bhi\bit\bte\bel\bli\bis\bst\bt t\bte\bes\bst\bt
 
 The postscreen_whitelist_networks parameter (default: $mynetworks) specifies a
 permanent whitelist for SMTP client IP addresses. When the SMTP client address
-matches the permanent whitelist, this is logged as:
+matches the permanent whitelist, postscreen(8) logs this with the client
+address and port number as:
 
-    W\bWH\bHI\bIT\bTE\bEL\bLI\bIS\bST\bTE\bED\baddress
+    W\bWH\bHI\bIT\bTE\bEL\bLI\bIS\bST\bTE\bED\b[address]:port
 
 The action is not configurable: immediately hand off the connection to a
 Postfix SMTP server process.
@@ -105,9 +106,9 @@ P\bPe\ber\brm\bma\ban\bne\ben\bnt\bt b\bbl\bla\bac\bck\bkl\bli\bis\bst\bt t\bte\bes\bst\bt
 The postscreen_blacklist_networks parameter (default: empty) specifies a
 permanent blacklist for SMTP client IP addresses. The address syntax is as with
 mynetworks. When the SMTP client address matches the permanent blacklist,
-postscreen(8) logs this as:
+postscreen(8) logs this with the client address and port number as:
 
-    B\bBL\bLA\bAC\bCK\bKL\bLI\bIS\bST\bTE\bED\baddress
+    B\bBL\bLA\bAC\bCK\bKL\bLI\bIS\bST\bTE\bED\b[address]:port
 
 The postscreen_blacklist_action parameter specifies the action that is taken
 next. See "When tests fail before the 220 SMTP server greeting" below.
@@ -121,9 +122,9 @@ whitelist. The temporary whitelist is not used for SMTP client addresses that
 appear on the permanent blacklist or whitelist.
 
 When the SMTP client address appears on the temporary whitelist, postscreen(8)
-logs this as:
+logs this with the client address and port number as:
 
-    P\bPA\bAS\bSS\bS O\bOL\bLD\baddress
+    P\bPA\bAS\bSS\bS O\bOL\bLD\b[address]:port
 
 The action is not configurable: immediately hand off the connection to a
 Postfix SMTP server process. The client is excluded from further tests until
@@ -174,12 +175,12 @@ postscreen_whitelist_networks feature or else specify an empty teaser banner:
 When an SMTP client sends a command before the postscreen_greet_wait time has
 elapsed, postscreen(8) logs this as:
 
-    P\bPR\bRE\bEG\bGR\bRE\bEE\bET\bT count a\baf\bft\bte\ber\br time f\bfr\bro\bom\baddress text...
+    P\bPR\bRE\bEG\bGR\bRE\bEE\bET\bT count a\baf\bft\bte\ber\br time f\bfr\bro\bom\b[address]:port text...
 
-Translation: the client at address sent count bytes before its turn to speak.
-This happened time seconds after the postscreen_greet_wait timer was started.
-The text is what the client sent (truncated to 100 bytes, and with non-
-printable characters replaced with "?").
+Translation: the client at [address]:port sent count bytes before its turn to
+speak. This happened time seconds after the postscreen_greet_wait timer was
+started. The text is what the client sent (truncated to 100 bytes, and with
+non-printable characters replaced with "?").
 
 The postscreen_greet_action parameter specifies the action that is taken next.
 See "When tests fail before the 220 SMTP server greeting" below.
@@ -199,9 +200,10 @@ When the postscreen_greet_wait time has elapsed, and the combined DNSBL score
 is equal to or greater than the postscreen_dnsbl_threshold parameter value,
 postscreen(8) logs this as:
 
-    D\bDN\bNS\bSB\bBL\bL r\bra\ban\bnk\bk count f\bfo\bor\baddress
+    D\bDN\bNS\bSB\bBL\bL r\bra\ban\bnk\bk count f\bfo\bor\b[address]:port
 
-Translation: the SMTP client at address has a combined DNSBL score of count.
+Translation: the SMTP client at [address]:port has a combined DNSBL score of
+count.
 
 The postscreen_dnsbl_action parameter specifies the action that is taken when
 the combined DNSBL score is equal to or greater than the threshold. See "When
@@ -278,11 +280,11 @@ in SMTP engine anyway. This is to make postscreen(8) logging more informative.
 
 When a client sends multiple commands, postscreen(8) logs this as:
 
-    C\bCO\bOM\bMM\bMA\bAN\bND\bD P\bPI\bIP\bPE\bEL\bLI\bIN\bNI\bIN\bNG\bG a\baf\bft\bte\ber\br time f\bfr\bro\bom\baddress
+    C\bCO\bOM\bMM\bMA\bAN\bND\bD P\bPI\bIP\bPE\bEL\bLI\bIN\bNI\bIN\bNG\bG a\baf\bft\bte\ber\br time f\bfr\bro\bom\b[address]:port
 
-Translation: the SMTP client at address sent multiple SMTP commands, instead of
-sending one command and then waiting for the server to reply. This happened
-time seconds after the "220 " server greeting was sent.
+Translation: the SMTP client at [address]:port sent multiple SMTP commands,
+instead of sending one command and then waiting for the server to reply. This
+happened time seconds after the "220 " server greeting was sent.
 
 The postscreen_pipelining_action parameter specifies the action that is taken
 next. See "When tests fail after the 220 SMTP server greeting" below.
@@ -306,9 +308,9 @@ in SMTP engine anyway. This is to make postscreen(8) logging more informative.
 
 When a client sends non-SMTP commands, postscreen(8) logs this as:
 
-    N\bNO\bON\bN-\b-S\bSM\bMT\bTP\bP C\bCO\bOM\bMM\bMA\bAN\bND\bD f\bfr\bro\bom\baddress command
+    N\bNO\bON\bN-\b-S\bSM\bMT\bTP\bP C\bCO\bOM\bMM\bMA\bAN\bND\bD f\bfr\bro\bom\b[address]:port command
 
-Translation: the SMTP client at address sent a command that matches the
+Translation: the SMTP client at [address]:port sent a command that matches the
 postscreen_forbidden_commands parameter, or that has the syntax of a message
 header label.
 
@@ -330,10 +332,10 @@ in SMTP engine anyway. This is to make postscreen(8) logging more informative.
 
 When a client sends bare newline characters, postscreen(8) logs this as:
 
-    B\bBA\bAR\bRE\bE N\bNE\bEW\bWL\bLI\bIN\bNE\bE f\bfr\bro\bom\baddress
+    B\bBA\bAR\bRE\bE N\bNE\bEW\bWL\bLI\bIN\bNE\bE f\bfr\bro\bom\b[address]:port
 
-Translation: the SMTP client at address sent a bare newline character, that is
-newline not preceded by carriage return.
+Translation: the SMTP client at [address]:port sent a bare newline character,
+that is newline not preceded by carriage return.
 
 The postscreen_bare_newline_action parameter specifies the action that is taken
 next. See "When tests fail after the 220 SMTP server greeting" below.
@@ -364,44 +366,54 @@ O\bOt\bth\bhe\ber\br e\ber\brr\bro\bor\brs\bs
 When an SMTP client hangs up unexpectedly during any tests, postscreen(8) logs
 this as:
 
-    H\bHA\bAN\bNG\bGU\bUP\bP a\baf\bft\bte\ber\br time f\bfr\bro\bom\baddress i\bin\bn test name
+    H\bHA\bAN\bNG\bGU\bUP\bP a\baf\bft\bte\ber\br time f\bfr\bro\bom\b[address]:port i\bin\bn test name
 
-Translation: the SMTP client at address disconnected unexpectedly, time seconds
-after the start of the test named test name.
+Translation: the SMTP client at [address]:port disconnected unexpectedly, time
+seconds after the start of the test named test name.
 
 The following errors are reported by the built-in SMTP engine. This engine
 never accepts mail, therefore it has per-session limits on the number of
 commands and on the session length.
 
-    C\bCO\bOM\bMM\bMA\bAN\bND\bD T\bTI\bIM\bME\bE L\bLI\bIM\bMI\bIT\bT f\bfr\bro\bom\baddress
+    C\bCO\bOM\bMM\bMA\bAN\bND\bD T\bTI\bIM\bME\bE L\bLI\bIM\bMI\bIT\bT f\bfr\bro\bom\b[address]:port
 
-Translation: the SMTP client at address reached the per-command time limit as
-specified with the postscreen_command_time_limit parameter. The session is
-terminated immediately.
+Translation: the SMTP client at [address]:port reached the per-command time
+limit as specified with the postscreen_command_time_limit parameter. The
+session is terminated immediately.
 
-    C\bCO\bOM\bMM\bMA\bAN\bND\bD C\bCO\bOU\bUN\bNT\bT L\bLI\bIM\bMI\bIT\bT f\bfr\bro\bom\baddress
+    C\bCO\bOM\bMM\bMA\bAN\bND\bD C\bCO\bOU\bUN\bNT\bT L\bLI\bIM\bMI\bIT\bT f\bfr\bro\bom\b[address]:port
 
-Translation: the SMTP client at address reached the per-session command count
-limit as specified with the postscreen_command_count_limit parameter. The
+Translation: the SMTP client at [address]:port reached the per-session command
+count limit as specified with the postscreen_command_count_limit parameter. The
 session is terminated immediately.
 
-    C\bCO\bOM\bMM\bMA\bAN\bND\bD L\bLE\bEN\bNG\bGT\bTH\bH L\bLI\bIM\bMI\bIT\bT f\bfr\bro\bom\bm address
+    C\bCO\bOM\bMM\bMA\bAN\bND\bD L\bLE\bEN\bNG\bGT\bTH\bH L\bLI\bIM\bMI\bIT\bT f\bfr\bro\bom\bm [address]:port
+
+Translation: the SMTP client at [address]:port reached the per-command length
+limit, as specified with the line_length_limit parameter. The session is
+terminated immediately.
+
+When an SMTP client makes too many connections at the same time, or when all
+postscreen(8) ports are busy, postscreen(8) rejects the connection with a 421
+status code and logs:
+
+    N\bNO\bOQ\bQU\bUE\bEU\bUE\bE:\b: r\bre\bej\bje\bec\bct\bt:\b: C\bCO\bON\bNN\bNE\bEC\bCT\bT f\bfr\bro\bom\bm [address]:port:\b: t\bto\boo\bo m\bma\ban\bny\by c\bco\bon\bnn\bne\bec\bct\bti\bio\bon\bns\bs
+    N\bNO\bOQ\bQU\bUE\bEU\bUE\bE:\b: r\bre\bej\bje\bec\bct\bt:\b: C\bCO\bON\bNN\bNE\bEC\bCT\bT f\bfr\bro\bom\bm [address]:port:\b: a\bal\bll\bl s\bse\ber\brv\bve\ber\br p\bpo\bor\brt\bts\bs b\bbu\bus\bsy\by
 
-Translation: the SMTP client at address reached the per-command length limit,
-as specified with the line_length_limit parameter. The session is terminated
-immediately.
+The postscreen_client_connection_count_limit and postscreen_pre_queue_limit
+parameters control these limits.
 
 W\bWh\bhe\ben\bn a\bal\bll\bl t\bte\bes\bst\bts\bs s\bsu\buc\bcc\bce\bee\bed\bd
 
 When a new SMTP client passes all tests (i.e. it is not whitelisted via some
 mechanism), postscreen(8) logs this as:
 
-    P\bPA\bAS\bSS\bS N\bNE\bEW\baddress
+    P\bPA\bAS\bSS\bS N\bNE\bEW\b[address]:port
 
-Where address is the client IP address. Then, postscreen(8) creates a temporary
-whitelist entry that excludes the client IP address from further tests until
-the temporary whitelist entry expires, as controlled with the postscreen_*_ttl
-parameters.
+Where [address]:port are the client IP address and port. Then, postscreen(8)
+creates a temporary whitelist entry that excludes the client IP address from
+further tests until the temporary whitelist entry expires, as controlled with
+the postscreen_*_ttl parameters.
 
 When no "deep protocol tests" are configured, postscreen(8) hands off the
 "live" connection to a Postfix SMTP server process. The client can then
index c226272603994730643deb88367e298d4a8d8ebf..501e4baac9818bfaafba5883d779a17050c6dac1 100644 (file)
@@ -33,12 +33,20 @@ This is supported only when the default value is stress-dependent
 postscreen parameters always evaluate as if the stress value is 
 equal to the empty string.
 
+Incompatibility with snapshot 20101130
+======================================
+
+The postscreen(8) daemon now logs the client as [address]:port.
+The port helps to distinguish between simultaneous sessions from
+the same address, and the [] allow the same tool to be used with
+old and new format logfiles, without producing errors for IPv6.
+
 Major changes with snapshot 20101126
 ====================================
 
 Support for address patterns in DNSBL and DNSWL lookup results. 
 
-For example, "reject_rbl_client example.com = 127.0.0.[2,4,6..8]"
+For example, "reject_rbl_client example.com=127.0.0.[2,4,6..8]"
 will reject clients when the lookup result is 127.0.0.2, 127.0.0.4,
 127.0.0.6, 127.0.0.7, or 127.0.0.8.
 
index a57d28a5960c0a31cd4e578c10a4d90940967a62..e9dd7ac95d82aaaaf9ad032688eb440d1f73e0b7 100644 (file)
@@ -4,13 +4,8 @@ Wish list:
 
        anvil rate limit for sasl_username.
 
-       postscreen per-client connection count limit.
-
        smtpd xclient option for sasl_username.
 
-       Documentation: add a note that smtpd_helo_required=yes is
-       needed to really enforce HELO restrictions.
-
        Use different ipc_timeout settings for email message
        transactions (smtpd, pickup)->cleanup and for quick query/reply
        transactions such as address rewriting/resolution.
index 4f2a1fd186838c3167272a66aea38867921067a2..b59eecd139c9691faf49f814e5c643b3fab10fca 100644 (file)
@@ -131,11 +131,11 @@ handling of known clients. </p>
 
 <p> The <a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> parameter (default: $<a href="postconf.5.html#mynetworks">mynetworks</a>)
 specifies a permanent whitelist for SMTP client IP addresses.  When
-the SMTP client address matches the permanent whitelist, this is
-logged as: </p>
+the SMTP client address matches the permanent whitelist, <a href="postscreen.8.html">postscreen(8)</a>
+logs this with the client address and port number as: </p>
 
 <pre>
-    <b>WHITELISTED</b> <i>address</i>
+    <b>WHITELISTED</b> <i>[address]:port</i>
 </pre>
 
 <p> The action is not configurable: immediately hand off the
@@ -146,10 +146,11 @@ connection to a Postfix SMTP server process. </p>
 <p> The <a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameter (default: empty)
 specifies a permanent blacklist for SMTP client IP addresses.  The
 address syntax is as with <a href="postconf.5.html#mynetworks">mynetworks</a>.  When the SMTP client address
-matches the permanent blacklist, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
+matches the permanent blacklist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the
+client address and port number as: </p>
 
 <pre>
-    <b>BLACKLISTED</b> <i>address</i>
+    <b>BLACKLISTED</b> <i>[address]:port</i>
 </pre>
 
 <p> The <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter specifies the action
@@ -166,10 +167,11 @@ temporary whitelist is not used for SMTP client addresses
 that appear on the <i>permanent</i> blacklist or whitelist. </p>
 
 <p> When the SMTP client address appears on the temporary
-whitelist, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
+whitelist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port
+number as: </p>
 
 <pre>
-    <b>PASS OLD</b> <i>address</i>
+    <b>PASS OLD</b> <i>[address]:port</i>
 </pre>
 
 <p> The action is not configurable: immediately hand off the
@@ -238,10 +240,10 @@ an empty teaser banner: </p>
 </p>
 
 <pre>
-    <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>address text...</i>
+    <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
 </pre>
 
-<p> Translation: the client at <i>address</i> sent <i>count</i>
+<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
 bytes before its turn to speak. This happened <i>time</i> seconds
 after the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> timer was started.  The <i>text</i>
 is what the client sent (truncated to 100 bytes, and with non-printable
@@ -271,10 +273,10 @@ DNSBL score is equal to or greater than the <a href="postconf.5.html#postscreen_
 parameter value, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
 
 <pre>
-    <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i>
+    <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> has a combined
+<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
 DNSBL score of <i>count</i>. </p>
 
 <p> The <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> parameter specifies the action that
@@ -380,10 +382,10 @@ logging more informative. </p>
 as: </p>
 
 <pre>
-    <b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>address</i>
+    <b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> sent multiple
+<p> Translation: the SMTP client at <i>[address]:port</i> sent multiple
 SMTP commands, instead of sending one command and then waiting for
 the server to reply. This happened <i>time</i> seconds after the
 "220 " server greeting was sent. </p>
@@ -416,10 +418,10 @@ logging more informative.  </p>
 as: </p>
 
 <pre>
-    <b>NON-SMTP COMMAND from</b> <i>address command</i>
+    <b>NON-SMTP COMMAND from</b> <i>[address]:port command</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> sent a
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a
 <i>command</i> that matches the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a>
 parameter, or that has the syntax of a message header label. </p>
 
@@ -448,10 +450,10 @@ this as:
 </p>
 
 <pre>
-    <b>BARE NEWLINE from</b> <i>address</i>
+    <b>BARE NEWLINE from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> sent a bare
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
 newline character, that is newline not preceded by carriage
 return. </p>
 
@@ -499,10 +501,10 @@ feature. </dd>
 <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
 
 <pre>
-    <b>HANGUP after</b> <i>time</i> <b>from</b> <i>address</i> <b>in</b> <i>test name</i>
+    <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> disconnected
+<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
 unexpectedly, <i>time</i> seconds after the start of the
 test named <i>test name</i>. </p>
 
@@ -513,7 +515,7 @@ allowed to pass any tests, and  <a href="postscreen.8.html">postscreen(8)</a> lo
 with the remaining amount of penalty time as: </p>
 
 <pre>
-    <b>PENALTY</b> <i>time</i> <b>for</b> <i>address</i>
+    <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
 </pre>
 
 <p> During this time, all attempts by the client to deliver mail
@@ -526,40 +528,53 @@ This engine never accepts mail, therefore it has per-session limits
 on the number of commands and on the session length. </p>
 
 <pre>
-    <b>COMMAND TIME LIMIT</b> <b>from</b> <i>address</i>
+    <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> reached the
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
 per-command time limit as specified with the <a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a>
 parameter.  The session is terminated immediately. </p>
 
 <pre>
-    <b>COMMAND COUNT LIMIT from</b> <i>address</i>
+    <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> reached the
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
 per-session command count limit as specified with the
 <a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> parameter.  The session is terminated
 immediately. </p>
 
 <pre>
-    <b>COMMAND LENGTH LIMIT from</b> <i>address</i>
+    <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> reached the
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
 per-command length limit, as specified with the <a href="postconf.5.html#line_length_limit">line_length_limit</a>
 parameter.  The session is terminated immediately. </p>
 
+<p> When an SMTP client makes too many connections at the same time,
+or when all <a href="postscreen.8.html">postscreen(8)</a> ports are busy, <a href="postscreen.8.html">postscreen(8)</a> rejects the
+connection with a 421 status code and logs: </p>
+
+<pre>
+    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
+    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
+</pre>
+
+<p> The <a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a> and
+<a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> parameters control these limits.  </p>
+
 <h2> <a name="victory">When all tests succeed</a> </h2>
 
 <p> When a new SMTP client passes all tests (i.e. it is not whitelisted
 via some mechanism), <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
 
 <pre>
-    <b>PASS NEW</b> <i>address</i>
+    <b>PASS NEW</b> <i>[address]:port</i>
 </pre>
 
-<p> Where <i>address</i> is the client IP address. Then, <a href="postscreen.8.html">postscreen(8)</a>
+<p> Where <i>[address]:port</i> are the client IP address and port.
+Then, <a href="postscreen.8.html">postscreen(8)</a>
 creates a temporary whitelist entry that excludes the client IP
 address from further tests until the temporary whitelist entry
 expires, as controlled with the postscreen_*_ttl parameters. </p>
index c9d86854b26c830ea1dbf65fbb65d3708f19d62a..37525409affe8b3509cd1426929de7ade867dbaf 100644 (file)
@@ -6782,6 +6782,21 @@ that passed some deep protocol test once and never came back. </p>
 <p> This feature is available in Postfix 2.8. </p>
 
 
+</DD>
+
+<DT><b><a name="postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a>
+(default: $<a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a>)</b></DT><DD>
+
+<p> How many simultaneous connections any client is allowed to have
+with the <a href="postscreen.8.html">postscreen(8)</a> daemon. By default, this limit is the same
+as with the Postfix SMTP server. Note that the triage process can
+take several seconds, with the time spent in <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a>
+delay, and with the time spent talking to the <a href="postscreen.8.html">postscreen(8)</a> built-in
+dummy SMTP protocol engine. </p>
+
+<p> This feature is available in Postfix 2.8.  </p>
+
+
 </DD>
 
 <DT><b><a name="postscreen_command_count_limit">postscreen_command_count_limit</a>
@@ -11680,8 +11695,8 @@ Postfix version 2.5).  This feature is available with Postfix version
 
 <dd>Reject the request when the reversed client network address is
 listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
-(Postfix version 2.1 and later only).  Each "<i>d</i>" can be a
-pattern inside "[]" that contains one or more comma-separated decimal
+(Postfix version 2.1 and later only).  Each "<i>d</i>" is a number,
+or a pattern inside "[]" that contains one or more comma-separated
 numbers or number..number ranges (Postfix version 2.8 and later).
 If no "<i>=d.d.d.d</i>" is specified, reject the request when the
 reversed client network address is listed with any A record under
@@ -11696,8 +11711,8 @@ This feature is available in Postfix 2.0 and later.  </dd>
 
 <dd>Accept the request when the reversed client network address is
 listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
-Each "<i>d</i>" can be a pattern inside "[]" that contains one or
-more comma-separated decimal numbers or number..number ranges.
+Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
+one or more comma-separated numbers or number..number ranges.
 If no "<i>=d.d.d.d</i>" is specified, accept the request when the
 reversed client network address is listed with any A record under
 <i>dnswl_domain</i>. <br> For safety, <a href="postconf.5.html#permit_dnswl_client">permit_dnswl_client</a> is silently
@@ -11709,8 +11724,8 @@ is available in Postfix 2.8 and later.  </dd>
 
 <dd>Reject the request when the client hostname is listed with the
 A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
-2.1 and later only).  Each "<i>d</i>" can be a pattern inside "[]"
-that contains one or more comma-separated decimal numbers or
+2.1 and later only).  Each "<i>d</i>" is a number, or a pattern
+inside "[]" that contains one or more comma-separated numbers or
 number..number ranges (Postfix version 2.8 and later).  If no
 "<i>=d.d.d.d</i>" is specified, reject the request when the client
 hostname is listed with
@@ -11724,8 +11739,8 @@ produce better results.  </dd>
 
 <dd>Accept the request when the client hostname is listed with the
 A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>.  Each "<i>d</i>"
-can be a pattern inside "[]" that contains one or more comma-separated
-decimal numbers or number..number ranges. If no
+is a number, or a pattern inside "[]" that contains one or more
+comma-separated numbers or number..number ranges. If no
 "<i>=d.d.d.d</i>" is specified, accept the request when the client
 hostname is listed with any A record under <i>rhswl_domain</i>.
 <br> Caution: client name whitelisting is fragile, since the client
@@ -11741,8 +11756,8 @@ when whitelist lookup fails.  This feature is available in Postfix
 
 <dd>Reject the request when the unverified reverse client hostname
 is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>.
-Each "<i>d</i>" can be a pattern inside "[]" that contains one or
-more comma-separated decimal numbers or number..number ranges.
+Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
+one or more comma-separated numbers or number..number ranges.
 If no "<i>=d.d.d.d</i>" is specified, reject the request when the
 unverified reverse client hostname is listed with any A record under
 <i>rbl_domain</i>. See the <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> description above for
@@ -12346,50 +12361,58 @@ received with the HELO or EHLO command.
 
 <dd>Search the specified <a href="access.5.html">access(5)</a> database for the HELO or EHLO
 hostname or parent domains, and execute the corresponding action.
-</dd>
+Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this
+restriction.  </dd>
 
 <dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
 
 <dd>Search the specified <a href="access.5.html">access(5)</a> database for the MX hosts for
 the HELO or EHLO hostname, and execute the corresponding action.
-Note: a result of "OK" is not allowed for safety reasons. Instead,
-use DUNNO in order to exclude specific hosts from blacklists.  This
-feature is available in Postfix 2.1 and later.  </dd>
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from blacklists.  Note
+2: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this
+restriction.  This feature is available in Postfix 2.1 and later.
+</dd>
 
 <dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
 
 <dd>Search the specified <a href="access.5.html">access(5)</a> database for the DNS servers
 for the HELO or EHLO hostname, and execute the corresponding action.
-Note: a result of "OK" is not allowed for safety reasons. Instead,
-use DUNNO in order to exclude specific hosts from blacklists.  This
-feature is available in Postfix 2.1 and later.  </dd>
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from blacklists.  Note
+2: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this
+restriction. This feature is available in Postfix 2.1 and later.
+</dd>
 
 <dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt>
 
 <dd>Reject the request when the HELO or EHLO hostname syntax is
-invalid. <br> The <a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> specifies the response
-code for rejected requests (default: 501).</dd>
+invalid. Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce
+this restriction. <br> The <a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> specifies
+the response code for rejected requests (default: 501).</dd>
 
 <dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt>
 
 <dd>Reject the request when the HELO or EHLO hostname is not in
-fully-qualified domain form, as required by the RFC. <br> The
-<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for
+fully-qualified domain form, as required by the RFC. Note: specify
+"<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this restriction.  <br>
+The <a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for
 rejected requests (default: 504).</dd>
 
 <dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
 
 <dd>Reject the request when the HELO or EHLO hostname hostname is
 listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
-(Postfix version 2.1 and later only).  Each "<i>d</i>" can be a
-pattern inside "[]" that contains one or more comma-separated decimal
+(Postfix version 2.1 and later only).  Each "<i>d</i>" is a number,
+or a pattern inside "[]" that contains one or more comma-separated
 numbers or number..number ranges (Postfix version 2.8 and later).
 If no "<i>=d.d.d.d</i>" is
 specified, reject the request when the HELO or EHLO hostname is
 listed with any A record under <i>rbl_domain</i>. See the
 <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> description for additional RBL related configuration
-parameters.  This feature is available in Postfix 2.0 and later.
-</dd>
+parameters.  Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully
+enforce this restriction. This feature is available in Postfix 2.0
+and later.  </dd>
 
 <dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt>
 
@@ -12398,7 +12421,8 @@ or MX record. <br> The <a href="postconf.5.html#unknown_hostname_reject_code">un
 specifies the numerical response code for rejected requests (default:
 450). <br> The <a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> parameter
 specifies the action after a temporary DNS error (default:
-<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). </dd>
+<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully
+enforce this restriction. </dd>
 
 </dl>
 
@@ -12800,8 +12824,8 @@ rejected requests (default: 504). </dd>
 
 <dd>Reject the request when the RCPT TO domain is listed with the
 A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
-2.1 and later only).  Each "<i>d</i>" can be a pattern inside "[]"
-that contains one or more comma-separated decimal numbers or
+2.1 and later only).  Each "<i>d</i>" is a number, or a pattern
+inside "[]" that contains one or more comma-separated numbers or
 number..number ranges (Postfix version 2.8 and later). If no
 "<i>=d.d.d.d</i>" is specified, reject
 the request when the RCPT TO domain is listed with
@@ -13347,8 +13371,8 @@ rejected requests (default: 504). </dd>
 
 <dd>Reject the request when the MAIL FROM domain is listed with
 the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix
-version 2.1 and later only).  Each "<i>d</i>" can be a pattern
-inside "[]" that contains one or more comma-separated decimal numbers
+version 2.1 and later only).  Each "<i>d</i>" is a number, or a
+pattern inside "[]" that contains one or more comma-separated numbers
 or number..number ranges (Postfix version 2.8 and later). If no
 "<i>=d.d.d.d</i>" is specified,
 reject the request when the MAIL FROM domain is
index 45a4c6f6732b45e8df240e2fa758efaa8eb73aba..b3c71a8bfeb528461bd49fc63d18ad9710a9b3ec 100644 (file)
@@ -233,41 +233,46 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               of  at  most this length; upon delivery, long lines
               are reconstructed.
 
+       <b><a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a></b>
+       <b>($<a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a>)</b>
+              How many simultaneous  connections  any  client  is
+              allowed to have with the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> daemon.
+
        <b><a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> (20)</b>
-              The limit on the total number of commands per  SMTP
-              session  for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol
+              The  limit on the total number of commands per SMTP
+              session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP  protocol
               engine.
 
        <b><a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> (${stress?10}${stress:300}s)</b>
-              The command "read" time limit  for  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s
+              The  command  "read" time limit for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s
               built-in SMTP protocol engine.
 
        <b><a href="postconf.5.html#postscreen_post_queue_limit">postscreen_post_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
-              The  number of clients that can be waiting for ser-
+              The number of clients that can be waiting for  ser-
               vice from a real SMTP server process.
 
        <b><a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
-              The number of non-whitelisted clients that  can  be
-              waiting  for  a  decision whether they will receive
+              The  number  of non-whitelisted clients that can be
+              waiting for a decision whether  they  will  receive
               service from a real SMTP server process.
 
        <b><a href="postconf.5.html#postscreen_watchdog_timeout">postscreen_watchdog_timeout</a> (10s)</b>
-              How much time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may  take  to
-              respond  to  an SMTP client command or to perform a
+              How  much  time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may take to
+              respond to an SMTP client command or to  perform  a
               cache operation before it is terminated by a built-
               in watchdog timer.
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix <a href="postconf.5.html">main.cf</a> and
+              The default location of  the  Postfix  <a href="postconf.5.html">main.cf</a>  and
               <a href="master.5.html">master.cf</a> configuration files.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number  of  digits  after  the  decimal
+              The  maximal  number  of  digits  after the decimal
               point when logging sub-second delay values.
 
        <b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
-              The  location  of  all  postfix administrative com-
+              The location of  all  postfix  administrative  com-
               mands.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
@@ -275,24 +280,24 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               over an internal communication channel.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The  maximum  amount  of  time that an idle Postfix
-              daemon process waits  for  an  incoming  connection
+              The maximum amount of time  that  an  idle  Postfix
+              daemon  process  waits  for  an incoming connection
               before terminating voluntarily.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The  process  ID  of  a  Postfix  command or daemon
+              The process ID  of  a  Postfix  command  or  daemon
               process.
 
        <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The process name of a  Postfix  command  or  daemon
+              The  process  name  of  a Postfix command or daemon
               process.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The  mail  system  name  that  is  prepended to the
-              process name in syslog  records,  so  that  "smtpd"
+              The mail system  name  that  is  prepended  to  the
+              process  name  in  syslog  records, so that "smtpd"
               becomes, for example, "postfix/smtpd".
 
 <b>SEE ALSO</b>
@@ -304,12 +309,12 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
        <a href="POSTSCREEN_README.html">POSTSCREEN_README</a>, Postfix Postscreen Howto
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>HISTORY</b>
-       Many  ideas in <a href="postscreen.8.html"><b>postscreen</b>(8)</a> were explored in earlier work
-       by Michael Tokarev, in OpenBSD spamd, and in  MailChannels
+       Many ideas in <a href="postscreen.8.html"><b>postscreen</b>(8)</a> were explored in earlier  work
+       by  Michael Tokarev, in OpenBSD spamd, and in MailChannels
        Traffic Control.
 
 <b>AUTHOR(S)</b>
index 3a98c78b89cfcb630fba1f89bd86f0e34f64701a..3df9798a7a9ba5816611f85326cfedfc870e1d42 100644 (file)
@@ -3818,6 +3818,15 @@ Time units: s (seconds), m (minutes), h (hours), d (days), w
 (weeks).
 .PP
 This feature is available in Postfix 2.8.
+.SH postscreen_client_connection_count_limit (default: $smtpd_client_connection_count_limit)
+How many simultaneous connections any client is allowed to have
+with the \fBpostscreen\fR(8) daemon. By default, this limit is the same
+as with the Postfix SMTP server. Note that the triage process can
+take several seconds, with the time spent in postscreen_greet_wait
+delay, and with the time spent talking to the \fBpostscreen\fR(8) built-in
+dummy SMTP protocol engine.
+.PP
+This feature is available in Postfix 2.8.
 .SH postscreen_command_count_limit (default: 20)
 The limit on the total number of commands per SMTP session for
 \fBpostscreen\fR(8)'s built-in SMTP protocol engine.  This SMTP engine
@@ -7166,8 +7175,8 @@ Postfix version 2.5).  This feature is available with Postfix version
 .IP "\fBreject_rbl_client \fIrbl_domain=d.d.d.d\fR\fR"
 Reject the request when the reversed client network address is
 listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR
-(Postfix version 2.1 and later only).  Each "\fId\fR" can be a
-pattern inside "[]" that contains one or more comma-separated decimal
+(Postfix version 2.1 and later only).  Each "\fId\fR" is a number,
+or a pattern inside "[]" that contains one or more comma-separated
 numbers or number..number ranges (Postfix version 2.8 and later).
 If no "\fI=d.d.d.d\fR" is specified, reject the request when the
 reversed client network address is listed with any A record under
@@ -7181,8 +7190,8 @@ This feature is available in Postfix 2.0 and later.
 .IP "\fBpermit_dnswl_client \fIdnswl_domain=d.d.d.d\fR\fR"
 Accept the request when the reversed client network address is
 listed with the A record "\fId.d.d.d\fR" under \fIdnswl_domain\fR.
-Each "\fId\fR" can be a pattern inside "[]" that contains one or
-more comma-separated decimal numbers or number..number ranges.
+Each "\fId\fR" is a number, or a pattern inside "[]" that contains
+one or more comma-separated numbers or number..number ranges.
 If no "\fI=d.d.d.d\fR" is specified, accept the request when the
 reversed client network address is listed with any A record under
 \fIdnswl_domain\fR.
@@ -7194,8 +7203,8 @@ is available in Postfix 2.8 and later.
 .IP "\fBreject_rhsbl_client \fIrbl_domain=d.d.d.d\fR\fR"
 Reject the request when the client hostname is listed with the
 A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version
-2.1 and later only).  Each "\fId\fR" can be a pattern inside "[]"
-that contains one or more comma-separated decimal numbers or
+2.1 and later only).  Each "\fId\fR" is a number, or a pattern
+inside "[]" that contains one or more comma-separated numbers or
 number..number ranges (Postfix version 2.8 and later).  If no
 "\fI=d.d.d.d\fR" is specified, reject the request when the client
 hostname is listed with
@@ -7207,8 +7216,8 @@ produce better results.
 .IP "\fBpermit_rhswl_client \fIrhswl_domain=d.d.d.d\fR\fR"
 Accept the request when the client hostname is listed with the
 A record "\fId.d.d.d\fR" under \fIrhswl_domain\fR.  Each "\fId\fR"
-can be a pattern inside "[]" that contains one or more comma-separated
-decimal numbers or number..number ranges. If no
+is a number, or a pattern inside "[]" that contains one or more
+comma-separated numbers or number..number ranges. If no
 "\fI=d.d.d.d\fR" is specified, accept the request when the client
 hostname is listed with any A record under \fIrhswl_domain\fR.
 .br
@@ -7224,8 +7233,8 @@ when whitelist lookup fails.  This feature is available in Postfix
 .IP "\fBreject_rhsbl_reverse_client \fIrbl_domain=d.d.d.d\fR\fR"
 Reject the request when the unverified reverse client hostname
 is listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR.
-Each "\fId\fR" can be a pattern inside "[]" that contains one or
-more comma-separated decimal numbers or number..number ranges.
+Each "\fId\fR" is a number, or a pattern inside "[]" that contains
+one or more comma-separated numbers or number..number ranges.
 If no "\fI=d.d.d.d\fR" is specified, reject the request when the
 unverified reverse client hostname is listed with any A record under
 \fIrbl_domain\fR. See the reject_rbl_client description above for
@@ -7666,42 +7675,49 @@ received with the HELO or EHLO command.
 .IP "\fBcheck_helo_access \fItype:table\fR\fR"
 Search the specified \fBaccess\fR(5) database for the HELO or EHLO
 hostname or parent domains, and execute the corresponding action.
+Note: specify "smtpd_helo_required = yes" to fully enforce this
+restriction.
 .IP "\fBcheck_helo_mx_access \fItype:table\fR\fR"
 Search the specified \fBaccess\fR(5) database for the MX hosts for
 the HELO or EHLO hostname, and execute the corresponding action.
-Note: a result of "OK" is not allowed for safety reasons. Instead,
-use DUNNO in order to exclude specific hosts from blacklists.  This
-feature is available in Postfix 2.1 and later.
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from blacklists.  Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction.  This feature is available in Postfix 2.1 and later.
 .IP "\fBcheck_helo_ns_access \fItype:table\fR\fR"
 Search the specified \fBaccess\fR(5) database for the DNS servers
 for the HELO or EHLO hostname, and execute the corresponding action.
-Note: a result of "OK" is not allowed for safety reasons. Instead,
-use DUNNO in order to exclude specific hosts from blacklists.  This
-feature is available in Postfix 2.1 and later.
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from blacklists.  Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction. This feature is available in Postfix 2.1 and later.
 .IP "\fBreject_invalid_helo_hostname\fR (with Postfix < 2.3: reject_invalid_hostname)"
 Reject the request when the HELO or EHLO hostname syntax is
-invalid.
+invalid. Note: specify "smtpd_helo_required = yes" to fully enforce
+this restriction.
 .br
-The invalid_hostname_reject_code specifies the response
-code for rejected requests (default: 501).
+The invalid_hostname_reject_code specifies
+the response code for rejected requests (default: 501).
 .IP "\fBreject_non_fqdn_helo_hostname\fR (with Postfix < 2.3: reject_non_fqdn_hostname)"
 Reject the request when the HELO or EHLO hostname is not in
-fully-qualified domain form, as required by the RFC.
+fully-qualified domain form, as required by the RFC. Note: specify
+"smtpd_helo_required = yes" to fully enforce this restriction.
 .br
-The
-non_fqdn_reject_code parameter specifies the response code for
+The non_fqdn_reject_code parameter specifies the response code for
 rejected requests (default: 504).
 .IP "\fBreject_rhsbl_helo \fIrbl_domain=d.d.d.d\fR\fR"
 Reject the request when the HELO or EHLO hostname hostname is
 listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR
-(Postfix version 2.1 and later only).  Each "\fId\fR" can be a
-pattern inside "[]" that contains one or more comma-separated decimal
+(Postfix version 2.1 and later only).  Each "\fId\fR" is a number,
+or a pattern inside "[]" that contains one or more comma-separated
 numbers or number..number ranges (Postfix version 2.8 and later).
 If no "\fI=d.d.d.d\fR" is
 specified, reject the request when the HELO or EHLO hostname is
 listed with any A record under \fIrbl_domain\fR. See the
 reject_rbl_client description for additional RBL related configuration
-parameters.  This feature is available in Postfix 2.0 and later.
+parameters.  Note: specify "smtpd_helo_required = yes" to fully
+enforce this restriction. This feature is available in Postfix 2.0
+and later.
 .IP "\fBreject_unknown_helo_hostname\fR (with Postfix < 2.3: reject_unknown_hostname)"
 Reject the request when the HELO or EHLO hostname has no DNS A
 or MX record.
@@ -7712,7 +7728,8 @@ specifies the numerical response code for rejected requests (default:
 .br
 The unknown_helo_hostname_tempfail_action parameter
 specifies the action after a temporary DNS error (default:
-defer_if_permit).
+defer_if_permit). Note: specify "smtpd_helo_required = yes" to fully
+enforce this restriction.
 .PP
 Other restrictions that are valid in this context:
 .IP \(bu
@@ -7939,8 +7956,8 @@ rejected requests (default: 504).
 .IP "\fBreject_rhsbl_recipient \fIrbl_domain=d.d.d.d\fR\fR"
 Reject the request when the RCPT TO domain is listed with the
 A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version
-2.1 and later only).  Each "\fId\fR" can be a pattern inside "[]"
-that contains one or more comma-separated decimal numbers or
+2.1 and later only).  Each "\fId\fR" is a number, or a pattern
+inside "[]" that contains one or more comma-separated numbers or
 number..number ranges (Postfix version 2.8 and later). If no
 "\fI=d.d.d.d\fR" is specified, reject
 the request when the RCPT TO domain is listed with
@@ -8312,8 +8329,8 @@ rejected requests (default: 504).
 .IP "\fBreject_rhsbl_sender \fIrbl_domain=d.d.d.d\fR\fR"
 Reject the request when the MAIL FROM domain is listed with
 the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix
-version 2.1 and later only).  Each "\fId\fR" can be a pattern
-inside "[]" that contains one or more comma-separated decimal numbers
+version 2.1 and later only).  Each "\fId\fR" is a number, or a
+pattern inside "[]" that contains one or more comma-separated numbers
 or number..number ranges (Postfix version 2.8 and later). If no
 "\fI=d.d.d.d\fR" is specified,
 reject the request when the MAIL FROM domain is
index c75c11feba1ba16eefbb6d3678dfcc04500ca167..09ed7de90e52eeeca778aa7086f842bd35b0f8e9 100644 (file)
@@ -210,6 +210,9 @@ a successful "pipelining" SMTP protocol test.
 .IP "\fBline_length_limit (2048)\fR"
 Upon input, long lines are chopped up into pieces of at most
 this length; upon delivery, long lines are reconstructed.
+.IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR"
+How many simultaneous connections any client is allowed to have
+with the \fBpostscreen\fR(8) daemon.
 .IP "\fBpostscreen_command_count_limit (20)\fR"
 The limit on the total number of commands per SMTP session for
 \fBpostscreen\fR(8)'s built-in SMTP protocol engine.
index f72c1aaeb5e00c10a2dabaced9e5f4ea56816f07..a20e3c2079e89d8f3e23604e02a7b06faf9bd6d5 100755 (executable)
@@ -944,6 +944,7 @@ while (<>) {
     s;\bpostscreen_whitelist_networks\b;<a href="postconf.5.html#postscreen_whitelist_networks">$&</a>;g;
     s;\bpostscreen_black[-</bB>]*\n*[ <bB>]*list_networks\b;<a href="postconf.5.html#postscreen_blacklist_networks">$&</a>;g;
     s;\bpostscreen_black[-</bB>]*\n*[ <bB>]*list_action\b;<a href="postconf.5.html#postscreen_blacklist_action">$&</a>;g;
+    s;\bpostscreen_client_connection_count_limit\b;<a href="postconf.5.html#postscreen_client_connection_count_limit">$&</a>;g;
 
     # Hyperlink URLs and RFC documents
 
index 2a7492f3242a98db5977769131f791926b5460ed..6d0c7e1662a003b22da04fd1d2ed5d7c6d63d825 100644 (file)
@@ -131,11 +131,11 @@ handling of known clients. </p>
 
 <p> The postscreen_whitelist_networks parameter (default: $mynetworks)
 specifies a permanent whitelist for SMTP client IP addresses.  When
-the SMTP client address matches the permanent whitelist, this is
-logged as: </p>
+the SMTP client address matches the permanent whitelist, postscreen(8)
+logs this with the client address and port number as: </p>
 
 <pre>
-    <b>WHITELISTED</b> <i>address</i>
+    <b>WHITELISTED</b> <i>[address]:port</i>
 </pre>
 
 <p> The action is not configurable: immediately hand off the
@@ -146,10 +146,11 @@ connection to a Postfix SMTP server process. </p>
 <p> The postscreen_blacklist_networks parameter (default: empty)
 specifies a permanent blacklist for SMTP client IP addresses.  The
 address syntax is as with mynetworks.  When the SMTP client address
-matches the permanent blacklist, postscreen(8) logs this as: </p>
+matches the permanent blacklist, postscreen(8) logs this with the
+client address and port number as: </p>
 
 <pre>
-    <b>BLACKLISTED</b> <i>address</i>
+    <b>BLACKLISTED</b> <i>[address]:port</i>
 </pre>
 
 <p> The postscreen_blacklist_action parameter specifies the action
@@ -166,10 +167,11 @@ temporary whitelist is not used for SMTP client addresses
 that appear on the <i>permanent</i> blacklist or whitelist. </p>
 
 <p> When the SMTP client address appears on the temporary
-whitelist, postscreen(8) logs this as: </p>
+whitelist, postscreen(8) logs this with the client address and port
+number as: </p>
 
 <pre>
-    <b>PASS OLD</b> <i>address</i>
+    <b>PASS OLD</b> <i>[address]:port</i>
 </pre>
 
 <p> The action is not configurable: immediately hand off the
@@ -238,10 +240,10 @@ postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
 </p>
 
 <pre>
-    <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>address text...</i>
+    <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
 </pre>
 
-<p> Translation: the client at <i>address</i> sent <i>count</i>
+<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
 bytes before its turn to speak. This happened <i>time</i> seconds
 after the postscreen_greet_wait timer was started.  The <i>text</i>
 is what the client sent (truncated to 100 bytes, and with non-printable
@@ -271,10 +273,10 @@ DNSBL score is equal to or greater than the postscreen_dnsbl_threshold
 parameter value, postscreen(8) logs this as: </p>
 
 <pre>
-    <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i>
+    <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> has a combined
+<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
 DNSBL score of <i>count</i>. </p>
 
 <p> The postscreen_dnsbl_action parameter specifies the action that
@@ -380,10 +382,10 @@ logging more informative. </p>
 as: </p>
 
 <pre>
-    <b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>address</i>
+    <b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> sent multiple
+<p> Translation: the SMTP client at <i>[address]:port</i> sent multiple
 SMTP commands, instead of sending one command and then waiting for
 the server to reply. This happened <i>time</i> seconds after the
 "220 " server greeting was sent. </p>
@@ -416,10 +418,10 @@ logging more informative.  </p>
 as: </p>
 
 <pre>
-    <b>NON-SMTP COMMAND from</b> <i>address command</i>
+    <b>NON-SMTP COMMAND from</b> <i>[address]:port command</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> sent a
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a
 <i>command</i> that matches the postscreen_forbidden_commands
 parameter, or that has the syntax of a message header label. </p>
 
@@ -448,10 +450,10 @@ this as:
 </p>
 
 <pre>
-    <b>BARE NEWLINE from</b> <i>address</i>
+    <b>BARE NEWLINE from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> sent a bare
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
 newline character, that is newline not preceded by carriage
 return. </p>
 
@@ -499,10 +501,10 @@ feature. </dd>
 postscreen(8) logs this as: </p>
 
 <pre>
-    <b>HANGUP after</b> <i>time</i> <b>from</b> <i>address</i> <b>in</b> <i>test name</i>
+    <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> disconnected
+<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
 unexpectedly, <i>time</i> seconds after the start of the
 test named <i>test name</i>. </p>
 
@@ -513,7 +515,7 @@ allowed to pass any tests, and  postscreen(8) logs each connection
 with the remaining amount of penalty time as: </p>
 
 <pre>
-    <b>PENALTY</b> <i>time</i> <b>for</b> <i>address</i>
+    <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
 </pre>
 
 <p> During this time, all attempts by the client to deliver mail
@@ -526,40 +528,53 @@ This engine never accepts mail, therefore it has per-session limits
 on the number of commands and on the session length. </p>
 
 <pre>
-    <b>COMMAND TIME LIMIT</b> <b>from</b> <i>address</i>
+    <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> reached the
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
 per-command time limit as specified with the postscreen_command_time_limit
 parameter.  The session is terminated immediately. </p>
 
 <pre>
-    <b>COMMAND COUNT LIMIT from</b> <i>address</i>
+    <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> reached the
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
 per-session command count limit as specified with the
 postscreen_command_count_limit parameter.  The session is terminated
 immediately. </p>
 
 <pre>
-    <b>COMMAND LENGTH LIMIT from</b> <i>address</i>
+    <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i>
 </pre>
 
-<p> Translation: the SMTP client at <i>address</i> reached the
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
 per-command length limit, as specified with the line_length_limit
 parameter.  The session is terminated immediately. </p>
 
+<p> When an SMTP client makes too many connections at the same time,
+or when all postscreen(8) ports are busy, postscreen(8) rejects the
+connection with a 421 status code and logs: </p>
+
+<pre>
+    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
+    <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
+</pre>
+
+<p> The postscreen_client_connection_count_limit and
+postscreen_pre_queue_limit parameters control these limits.  </p>
+
 <h2> <a name="victory">When all tests succeed</a> </h2>
 
 <p> When a new SMTP client passes all tests (i.e. it is not whitelisted
 via some mechanism), postscreen(8) logs this as: </p>
 
 <pre>
-    <b>PASS NEW</b> <i>address</i>
+    <b>PASS NEW</b> <i>[address]:port</i>
 </pre>
 
-<p> Where <i>address</i> is the client IP address. Then, postscreen(8)
+<p> Where <i>[address]:port</i> are the client IP address and port.
+Then, postscreen(8)
 creates a temporary whitelist entry that excludes the client IP
 address from further tests until the temporary whitelist entry
 expires, as controlled with the postscreen_*_ttl parameters. </p>
index 16d9d3942b1f5ccabd2aa26a0b431545fe178be5..7334ea0790211fd0629b7aea47358308fc32b4cf 100644 (file)
@@ -4879,8 +4879,8 @@ Postfix version 2.5).  This feature is available with Postfix version
 
 <dd>Reject the request when the reversed client network address is
 listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
-(Postfix version 2.1 and later only).  Each "<i>d</i>" can be a
-pattern inside "[]" that contains one or more comma-separated decimal
+(Postfix version 2.1 and later only).  Each "<i>d</i>" is a number,
+or a pattern inside "[]" that contains one or more comma-separated
 numbers or number..number ranges (Postfix version 2.8 and later).
 If no "<i>=d.d.d.d</i>" is specified, reject the request when the
 reversed client network address is listed with any A record under
@@ -4895,8 +4895,8 @@ This feature is available in Postfix 2.0 and later.  </dd>
 
 <dd>Accept the request when the reversed client network address is
 listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
-Each "<i>d</i>" can be a pattern inside "[]" that contains one or
-more comma-separated decimal numbers or number..number ranges.
+Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
+one or more comma-separated numbers or number..number ranges.
 If no "<i>=d.d.d.d</i>" is specified, accept the request when the
 reversed client network address is listed with any A record under
 <i>dnswl_domain</i>. <br> For safety, permit_dnswl_client is silently
@@ -4908,8 +4908,8 @@ is available in Postfix 2.8 and later.  </dd>
 
 <dd>Reject the request when the client hostname is listed with the
 A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
-2.1 and later only).  Each "<i>d</i>" can be a pattern inside "[]"
-that contains one or more comma-separated decimal numbers or
+2.1 and later only).  Each "<i>d</i>" is a number, or a pattern
+inside "[]" that contains one or more comma-separated numbers or
 number..number ranges (Postfix version 2.8 and later).  If no
 "<i>=d.d.d.d</i>" is specified, reject the request when the client
 hostname is listed with
@@ -4923,8 +4923,8 @@ produce better results.  </dd>
 
 <dd>Accept the request when the client hostname is listed with the
 A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>.  Each "<i>d</i>"
-can be a pattern inside "[]" that contains one or more comma-separated
-decimal numbers or number..number ranges. If no
+is a number, or a pattern inside "[]" that contains one or more
+comma-separated numbers or number..number ranges. If no
 "<i>=d.d.d.d</i>" is specified, accept the request when the client
 hostname is listed with any A record under <i>rhswl_domain</i>.
 <br> Caution: client name whitelisting is fragile, since the client
@@ -4940,8 +4940,8 @@ when whitelist lookup fails.  This feature is available in Postfix
 
 <dd>Reject the request when the unverified reverse client hostname
 is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>.
-Each "<i>d</i>" can be a pattern inside "[]" that contains one or
-more comma-separated decimal numbers or number..number ranges.
+Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
+one or more comma-separated numbers or number..number ranges.
 If no "<i>=d.d.d.d</i>" is specified, reject the request when the
 unverified reverse client hostname is listed with any A record under
 <i>rbl_domain</i>. See the reject_rbl_client description above for
@@ -5346,50 +5346,58 @@ received with the HELO or EHLO command.
 
 <dd>Search the specified access(5) database for the HELO or EHLO
 hostname or parent domains, and execute the corresponding action.
-</dd>
+Note: specify "smtpd_helo_required = yes" to fully enforce this
+restriction.  </dd>
 
 <dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
 
 <dd>Search the specified access(5) database for the MX hosts for
 the HELO or EHLO hostname, and execute the corresponding action.
-Note: a result of "OK" is not allowed for safety reasons. Instead,
-use DUNNO in order to exclude specific hosts from blacklists.  This
-feature is available in Postfix 2.1 and later.  </dd>
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from blacklists.  Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction.  This feature is available in Postfix 2.1 and later.
+</dd>
 
 <dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
 
 <dd>Search the specified access(5) database for the DNS servers
 for the HELO or EHLO hostname, and execute the corresponding action.
-Note: a result of "OK" is not allowed for safety reasons. Instead,        
-use DUNNO in order to exclude specific hosts from blacklists.  This
-feature is available in Postfix 2.1 and later.  </dd>
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from blacklists.  Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction. This feature is available in Postfix 2.1 and later.
+</dd>
 
 <dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt>
 
 <dd>Reject the request when the HELO or EHLO hostname syntax is
-invalid. <br> The invalid_hostname_reject_code specifies the response
-code for rejected requests (default: 501).</dd>
+invalid. Note: specify "smtpd_helo_required = yes" to fully enforce
+this restriction. <br> The invalid_hostname_reject_code specifies
+the response code for rejected requests (default: 501).</dd>
 
 <dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt>
 
 <dd>Reject the request when the HELO or EHLO hostname is not in
-fully-qualified domain form, as required by the RFC. <br> The
-non_fqdn_reject_code parameter specifies the response code for
+fully-qualified domain form, as required by the RFC. Note: specify
+"smtpd_helo_required = yes" to fully enforce this restriction.  <br>
+The non_fqdn_reject_code parameter specifies the response code for
 rejected requests (default: 504).</dd>
 
 <dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
 
 <dd>Reject the request when the HELO or EHLO hostname hostname is
 listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
-(Postfix version 2.1 and later only).  Each "<i>d</i>" can be a
-pattern inside "[]" that contains one or more comma-separated decimal
+(Postfix version 2.1 and later only).  Each "<i>d</i>" is a number,
+or a pattern inside "[]" that contains one or more comma-separated
 numbers or number..number ranges (Postfix version 2.8 and later).
 If no "<i>=d.d.d.d</i>" is
 specified, reject the request when the HELO or EHLO hostname is
 listed with any A record under <i>rbl_domain</i>. See the
 reject_rbl_client description for additional RBL related configuration
-parameters.  This feature is available in Postfix 2.0 and later.
-</dd>
+parameters.  Note: specify "smtpd_helo_required = yes" to fully
+enforce this restriction. This feature is available in Postfix 2.0
+and later.  </dd>
 
 <dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt>
 
@@ -5398,7 +5406,8 @@ or MX record. <br> The unknown_hostname_reject_code parameter
 specifies the numerical response code for rejected requests (default:
 450). <br> The unknown_helo_hostname_tempfail_action parameter
 specifies the action after a temporary DNS error (default:
-defer_if_permit). </dd>
+defer_if_permit). Note: specify "smtpd_helo_required = yes" to fully
+enforce this restriction. </dd>
 
 </dl>
 
@@ -5674,8 +5683,8 @@ rejected requests (default: 504). </dd>
 
 <dd>Reject the request when the RCPT TO domain is listed with the
 A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
-2.1 and later only).  Each "<i>d</i>" can be a pattern inside "[]"
-that contains one or more comma-separated decimal numbers or
+2.1 and later only).  Each "<i>d</i>" is a number, or a pattern
+inside "[]" that contains one or more comma-separated numbers or
 number..number ranges (Postfix version 2.8 and later). If no
 "<i>=d.d.d.d</i>" is specified, reject
 the request when the RCPT TO domain is listed with
@@ -6052,8 +6061,8 @@ rejected requests (default: 504). </dd>
 
 <dd>Reject the request when the MAIL FROM domain is listed with
 the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix
-version 2.1 and later only).  Each "<i>d</i>" can be a pattern
-inside "[]" that contains one or more comma-separated decimal numbers
+version 2.1 and later only).  Each "<i>d</i>" is a number, or a
+pattern inside "[]" that contains one or more comma-separated numbers
 or number..number ranges (Postfix version 2.8 and later). If no
 "<i>=d.d.d.d</i>" is specified,
 reject the request when the MAIL FROM domain is
@@ -13331,6 +13340,17 @@ it passes the test, before it can talk to a real Postfix SMTP server.
 
 <p> This feature is available in Postfix 2.8.  </p>
 
+%PARAM postscreen_client_connection_count_limit $smtpd_client_connection_count_limit
+
+<p> How many simultaneous connections any client is allowed to have
+with the postscreen(8) daemon. By default, this limit is the same
+as with the Postfix SMTP server. Note that the triage process can
+take several seconds, with the time spent in postscreen_greet_wait
+delay, and with the time spent talking to the postscreen(8) built-in
+dummy SMTP protocol engine. </p>
+
+<p> This feature is available in Postfix 2.8.  </p>
+
 %PARAM dnsblog_reply_delay 0s
 
 <p> A debugging aid to artifically delay DNS responses. </p>
index 7901248cd7093355ca638f172e5c08eaacaeed1c..09b4a7d58081e5b191050c822b4755e8638ac281 100644 (file)
@@ -3366,6 +3366,10 @@ extern bool var_ps_helo_required;
 #define DEF_PS_DISABLE_VRFY    "$" VAR_DISABLE_VRFY_CMD
 extern bool var_ps_disable_vrfy;
 
+#define VAR_PS_CCONN_LIMIT     "postscreen_client_connection_count_limit"
+#define DEF_PS_CCONN_LIMIT     "$" VAR_SMTPD_CCONN_LIMIT
+extern int var_ps_cconn_limit;
+
 #define VAR_DNSBLOG_DELAY      "dnsblog_reply_delay"
 #define DEF_DNSBLOG_DELAY      "0s"
 extern int var_dnsblog_delay;
index a5e6a34bb6141fd2f581777ec656196271ee0d16..6758078fd5acff8ee126b473749f7793b53194dc 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      "20101126"
+#define MAIL_RELEASE_DATE      "20101130"
 #define MAIL_VERSION_NUMBER    "2.8"
 
 #ifdef SNAPSHOT
index 6957030b2c09bab24090e37e7efd8ac778456e65..227e211a5713866442001dd0863cfe4f06befbbe 100644 (file)
@@ -68,6 +68,7 @@ postscreen.o: ../../include/data_redirect.h
 postscreen.o: ../../include/dict.h
 postscreen.o: ../../include/dict_cache.h
 postscreen.o: ../../include/events.h
+postscreen.o: ../../include/htable.h
 postscreen.o: ../../include/iostuff.h
 postscreen.o: ../../include/mail_conf.h
 postscreen.o: ../../include/mail_params.h
@@ -93,6 +94,7 @@ postscreen_dict.o: ../../include/argv.h
 postscreen_dict.o: ../../include/dict.h
 postscreen_dict.o: ../../include/dict_cache.h
 postscreen_dict.o: ../../include/events.h
+postscreen_dict.o: ../../include/htable.h
 postscreen_dict.o: ../../include/match_list.h
 postscreen_dict.o: ../../include/match_ops.h
 postscreen_dict.o: ../../include/msg.h
@@ -118,6 +120,7 @@ postscreen_dnsbl.o: ../../include/mail_proto.h
 postscreen_dnsbl.o: ../../include/match_list.h
 postscreen_dnsbl.o: ../../include/match_ops.h
 postscreen_dnsbl.o: ../../include/msg.h
+postscreen_dnsbl.o: ../../include/myaddrinfo.h
 postscreen_dnsbl.o: ../../include/mymalloc.h
 postscreen_dnsbl.o: ../../include/split_at.h
 postscreen_dnsbl.o: ../../include/string_list.h
@@ -133,6 +136,7 @@ postscreen_early.o: ../../include/argv.h
 postscreen_early.o: ../../include/dict.h
 postscreen_early.o: ../../include/dict_cache.h
 postscreen_early.o: ../../include/events.h
+postscreen_early.o: ../../include/htable.h
 postscreen_early.o: ../../include/mail_params.h
 postscreen_early.o: ../../include/match_list.h
 postscreen_early.o: ../../include/match_ops.h
@@ -152,6 +156,7 @@ postscreen_misc.o: ../../include/dict.h
 postscreen_misc.o: ../../include/dict_cache.h
 postscreen_misc.o: ../../include/events.h
 postscreen_misc.o: ../../include/format_tv.h
+postscreen_misc.o: ../../include/htable.h
 postscreen_misc.o: ../../include/iostuff.h
 postscreen_misc.o: ../../include/mail_params.h
 postscreen_misc.o: ../../include/match_list.h
@@ -170,6 +175,7 @@ postscreen_send.o: ../../include/connect.h
 postscreen_send.o: ../../include/dict.h
 postscreen_send.o: ../../include/dict_cache.h
 postscreen_send.o: ../../include/events.h
+postscreen_send.o: ../../include/htable.h
 postscreen_send.o: ../../include/iostuff.h
 postscreen_send.o: ../../include/match_list.h
 postscreen_send.o: ../../include/match_ops.h
@@ -187,6 +193,7 @@ postscreen_smtpd.o: ../../include/attr.h
 postscreen_smtpd.o: ../../include/dict.h
 postscreen_smtpd.o: ../../include/dict_cache.h
 postscreen_smtpd.o: ../../include/events.h
+postscreen_smtpd.o: ../../include/htable.h
 postscreen_smtpd.o: ../../include/iostuff.h
 postscreen_smtpd.o: ../../include/is_header.h
 postscreen_smtpd.o: ../../include/mail_params.h
@@ -209,6 +216,7 @@ postscreen_state.o: ../../include/attr.h
 postscreen_state.o: ../../include/dict.h
 postscreen_state.o: ../../include/dict_cache.h
 postscreen_state.o: ../../include/events.h
+postscreen_state.o: ../../include/htable.h
 postscreen_state.o: ../../include/iostuff.h
 postscreen_state.o: ../../include/mail_proto.h
 postscreen_state.o: ../../include/mail_server.h
@@ -229,6 +237,7 @@ postscreen_tests.o: ../../include/argv.h
 postscreen_tests.o: ../../include/dict.h
 postscreen_tests.o: ../../include/dict_cache.h
 postscreen_tests.o: ../../include/events.h
+postscreen_tests.o: ../../include/htable.h
 postscreen_tests.o: ../../include/mail_params.h
 postscreen_tests.o: ../../include/match_list.h
 postscreen_tests.o: ../../include/match_ops.h
index 74a32f4e4eb737afcc7818837b505decf99b93de..37fca2746db9007d044036f91a52cc91a080aaa7 100644 (file)
 /* .IP "\fBline_length_limit (2048)\fR"
 /*     Upon input, long lines are chopped up into pieces of at most
 /*     this length; upon delivery, long lines are reconstructed.
+/* .IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR"
+/*     How many simultaneous connections any client is allowed to have
+/*     with the \fBpostscreen\fR(8) daemon.
 /* .IP "\fBpostscreen_command_count_limit (20)\fR"
 /*     The limit on the total number of commands per SMTP session for
 /*     \fBpostscreen\fR(8)'s built-in SMTP protocol engine.
@@ -348,6 +351,8 @@ int     var_ps_barlf_ttl;
 int     var_ps_cmd_count;
 char   *var_ps_cmd_time;
 
+int     var_ps_cconn_limit;
+
  /*
   * Global variables.
   */
@@ -372,6 +377,7 @@ int     ps_stress;                  /* stress level */
 int     ps_check_queue_length_lowat;   /* stress low-water mark */
 int     ps_check_queue_length_hiwat;   /* stress high-water mark */
 DICT   *ps_dnsbl_reply;                        /* DNSBL name mapper */
+HTABLE *ps_client_concurrency;         /* per-client concurrency */
 
  /*
   * Local variables.
@@ -501,11 +507,11 @@ static void ps_service(VSTREAM *smtp_client_stream,
        memmove(smtp_client_addr.buf, smtp_client_addr.buf + 7,
                sizeof(smtp_client_addr.buf) - 7);
     if (msg_verbose > 1)
-       msg_info("%s: sq=%d cq=%d connect from %s:%s",
+       msg_info("%s: sq=%d cq=%d connect from [%s]:%s",
                 myname, ps_post_queue_length, ps_check_queue_length,
                 smtp_client_addr.buf, smtp_client_port.buf);
 
-    msg_info("CONNECT from %s", smtp_client_addr.buf);
+    msg_info("CONNECT from [%s]:%s", smtp_client_addr.buf, smtp_client_port.buf);
 
     /*
      * Bundle up all the loose session pieces. This zeroes all flags and time
@@ -514,12 +520,24 @@ static void ps_service(VSTREAM *smtp_client_stream,
     state = ps_new_session_state(smtp_client_stream, smtp_client_addr.buf,
                                 smtp_client_port.buf);
 
+    /*
+     * Reply with 421 when the client has too many open connections.
+     */
+    if (var_ps_cconn_limit > 0
+       && state->client_concurrency  > var_ps_cconn_limit) {
+       msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: too many connections",
+                state->smtp_client_addr, state->smtp_client_port);
+       PS_DROP_SESSION_STATE(state,
+                             "421 4.7.0 Error: too many connections\r\n");
+       return;
+    }
+
     /*
      * Reply with 421 when we can't forward more connections.
      */
     if (var_ps_post_queue_limit > 0
        && ps_post_queue_length >= var_ps_post_queue_limit) {
-       msg_info("reject: connect from %s:%s: all server ports busy",
+       msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: all server ports busy",
                 state->smtp_client_addr, state->smtp_client_port);
        PS_DROP_SESSION_STATE(state,
                              "421 4.3.2 All server ports are busy\r\n");
@@ -532,7 +550,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
      */
     if (ps_wlist_nets != 0
       && ps_addr_match_list_match(ps_wlist_nets, state->smtp_client_addr)) {
-       msg_info("WHITELISTED %s", state->smtp_client_addr);
+       msg_info("WHITELISTED [%s]:%s", PS_CLIENT_ADDR_PORT(state));
        ps_conclude(state);
        return;
     }
@@ -544,7 +562,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
      */
     if (ps_blist_nets != 0
       && ps_addr_match_list_match(ps_blist_nets, state->smtp_client_addr)) {
-       msg_info("BLACKLISTED %s", state->smtp_client_addr);
+       msg_info("BLACKLISTED [%s]:%s", PS_CLIENT_ADDR_PORT(state));
        PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BLIST_FAIL);
        switch (ps_blist_action) {
        case PS_ACT_DROP:
@@ -581,7 +599,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
            msg_info("%s: cached + recent flags: %s",
                     myname, ps_print_state_flags(state->flags, myname));
        if ((state->flags & PS_STATE_MASK_ANY_TODO_FAIL) == 0) {
-           msg_info("PASS OLD %s", state->smtp_client_addr);
+           msg_info("PASS OLD [%s]:%s", PS_CLIENT_ADDR_PORT(state));
            ps_conclude(state);
            return;
        }
@@ -599,7 +617,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
      */
     if (var_ps_pre_queue_limit > 0
        && ps_check_queue_length - ps_post_queue_length >= var_ps_pre_queue_limit) {
-       msg_info("reject: connect from %s:%s: all screening ports busy",
+       msg_info("reject: connect from [%s]:%s: all screening ports busy",
                 state->smtp_client_addr, state->smtp_client_port);
        PS_DROP_SESSION_STATE(state,
                              "421 4.3.2 All screening ports are busy\r\n");
@@ -807,6 +825,11 @@ static void post_jail_init(char *unused_name, char **unused_argv)
        msg_info(VAR_PS_CMD_TIME ": stress=%d normal=%d lowat=%d hiwat=%d",
                 ps_stress_cmd_time_limit, ps_normal_cmd_time_limit,
                 ps_check_queue_length_lowat, ps_check_queue_length_hiwat);
+
+    /*
+     * Per-client concurrency.
+     */
+    ps_client_concurrency = htable_create(var_ps_pre_queue_limit);
 }
 
 MAIL_VERSION_STAMP_DECLARE;
@@ -848,6 +871,7 @@ int     main(int argc, char **argv)
     static const CONFIG_NINT_TABLE nint_table[] = {
        VAR_PS_POST_QLIMIT, DEF_PS_POST_QLIMIT, &var_ps_post_queue_limit, 5, 0,
        VAR_PS_PRE_QLIMIT, DEF_PS_PRE_QLIMIT, &var_ps_pre_queue_limit, 10, 0,
+       VAR_PS_CCONN_LIMIT, DEF_PS_CCONN_LIMIT, &var_ps_cconn_limit, 0, 0,
        0,
     };
     static const CONFIG_TIME_TABLE time_table[] = {
index 4470756b39d97c6d61a786ffcbe7fc6d4321ef6d..a93a036bb4e8e2dea8ef4aa3df38d63547c70ebf 100644 (file)
@@ -19,6 +19,7 @@
 #include <vstream.h>
 #include <vstring.h>
 #include <events.h>
+#include <htable.h>
 
  /*
   * Global library.
@@ -41,6 +42,7 @@ typedef struct {
     int     smtp_server_fd;            /* real SMTP server */
     char   *smtp_client_addr;          /* client address */
     char   *smtp_client_port;          /* client port */
+    int     client_concurrency;                /* per-client */
     const char *final_reply;           /* cause for hanging up */
     /* Test context. */
     struct timeval start_time;         /* start of current test */
@@ -288,6 +290,7 @@ extern int ps_stress;                       /* stress level */
 extern int ps_check_queue_length_lowat;        /* stress low-water mark */
 extern int ps_check_queue_length_hiwat;        /* stress high-water mark */
 extern DICT *ps_dnsbl_reply;           /* DNSBL name mapper */
+extern HTABLE *ps_client_concurrency;  /* per-client concurrency */
 
 #define PS_EFF_GREET_WAIT \
        (ps_stress ? ps_stress_greet_wait : ps_normal_greet_wait)
@@ -323,40 +326,40 @@ extern DICT *ps_dnsbl_reply;              /* DNSBL name mapper */
 
 #define PS_PASS_SESSION_STATE(state, what, bits) do { \
        if (msg_verbose) \
-           msg_info("PASS %s %s:%s", (what), PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("PASS %s [%s]:%s", (what), PS_CLIENT_ADDR_PORT(state)); \
        (state)->flags |= (bits); \
     } while (0)
 #define PS_FAIL_SESSION_STATE(state, bits) do { \
        if (msg_verbose) \
-           msg_info("FAIL %s:%s", PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("FAIL [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
        (state)->flags |= (bits); \
     } while (0)
 #define PS_SKIP_SESSION_STATE(state, what, bits) do { \
        if (msg_verbose) \
-           msg_info("SKIP %s %s:%s", (what), PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("SKIP %s [%s]:%s", (what), PS_CLIENT_ADDR_PORT(state)); \
        (state)->flags |= (bits); \
     } while (0)
 #define PS_DROP_SESSION_STATE(state, reply) do { \
        if (msg_verbose) \
-           msg_info("DROP %s:%s", PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("DROP [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
        (state)->flags |= PS_STATE_FLAG_NOFORWARD; \
        (state)->final_reply = (reply); \
        ps_conclude(state); \
     } while (0)
 #define PS_ENFORCE_SESSION_STATE(state, reply) do { \
        if (msg_verbose) \
-           msg_info("ENFORCE %s:%s", PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("ENFORCE [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
        (state)->rcpt_reply = (reply); \
        (state)->flags |= PS_STATE_FLAG_NOFORWARD; \
     } while (0)
 #define PS_UNPASS_SESSION_STATE(state, bits) do { \
        if (msg_verbose) \
-           msg_info("UNPASS %s:%s", PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("UNPASS [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
        (state)->flags &= ~(bits); \
     } while (0)
 #define PS_UNFAIL_SESSION_STATE(state, bits) do { \
        if (msg_verbose) \
-           msg_info("UNFAIL %s:%s", PS_CLIENT_ADDR_PORT(state)); \
+           msg_info("UNFAIL [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
        (state)->flags &= ~(bits); \
     } while (0)
 #define PS_ADD_SERVER_STATE(state, fd) do { \
index d28c90e426122d26cdce478519fba29f0d0256b1..2b68b00972d15053e12a67156c472bfbec93b3d5 100644 (file)
@@ -107,7 +107,8 @@ typedef struct {
 } PS_DNSBL_HEAD;
 
 typedef struct PS_DNSBL_SITE {
-    char   *filter;                    /* reply filter (default: null) */
+    char   *filter;                    /* printable filter (default: null) */
+    char   *byte_codes;                        /* encoded filter (default: null) */
     int     weight;                    /* reply weight (default: 1) */
     struct PS_DNSBL_SITE *next;                /* linked list */
 } PS_DNSBL_SITE;
@@ -209,7 +210,7 @@ static void ps_dnsbl_add_site(const char *site)
     PS_DNSBL_SITE *new_site;
     char    junk;
     const char *weight_text;
-    char *pattern_text;
+    char   *pattern_text;
     int     weight;
     HTABLE_INFO *ht;
     char   *parse_err;
@@ -263,7 +264,8 @@ static void ps_dnsbl_add_site(const char *site)
      * name.
      */
     new_site = (PS_DNSBL_SITE *) mymalloc(sizeof(*new_site));
-    new_site->filter = (pattern_text ? ip_match_save(byte_codes) : 0);
+    new_site->filter = (pattern_text ? mystrdup(pattern_text) : 0);
+    new_site->byte_codes = (byte_codes ? ip_match_save(byte_codes) : 0);
     new_site->weight = weight;
     new_site->next = head->first;
     head->first = new_site;
@@ -382,8 +384,8 @@ static void ps_dnsbl_receive(int event, char *context)
                htable_find(dnsbl_site_cache, STR(reply_dnsbl));
            site = (head ? head->first : (PS_DNSBL_SITE *) 0);
            for (reply_argv = 0; site != 0; site = site->next) {
-               if (site->filter == 0
-                   || ps_dnsbl_match(site->filter, reply_argv ? reply_argv :
+               if (site->byte_codes == 0
+               || ps_dnsbl_match(site->byte_codes, reply_argv ? reply_argv :
                         (reply_argv = argv_split(STR(reply_addr), " ")))) {
                    if (score->dnsbl == 0)
                        score->dnsbl = head->safe_dnsbl;
index 27e22e2841c5169291422239abb917252f0aedd2..54e27bc712c4cf7ffa0888899562991da633bd25 100644 (file)
@@ -62,7 +62,7 @@ static void ps_early_event(int event, char *context)
     const char *dnsbl_name;
 
     if (msg_verbose > 1)
-       msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from %s:%s flags=%s",
+       msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
                 myname, ps_post_queue_length, ps_check_queue_length,
                 event, vstream_fileno(state->smtp_client_stream),
                 state->smtp_client_addr, state->smtp_client_port,
@@ -117,8 +117,8 @@ static void ps_early_event(int event, char *context)
                PS_PASS_SESSION_STATE(state, "dnsbl test",
                                      PS_STATE_FLAG_DNSBL_PASS);
            } else {
-               msg_info("DNSBL rank %d for %s",
-                        dnsbl_score, state->smtp_client_addr);
+               msg_info("DNSBL rank %d for [%s]:%s",
+                        dnsbl_score, PS_CLIENT_ADDR_PORT(state));
                PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_DNSBL_FAIL);
                switch (ps_dnsbl_action) {
                case PS_ACT_DROP:
@@ -174,9 +174,9 @@ static void ps_early_event(int event, char *context)
            return;
        }
        read_buf[read_count] = 0;
-       msg_info("PREGREET %d after %s from %s: %.100s", read_count,
+       msg_info("PREGREET %d after %s from [%s]:%s: %.100s", read_count,
                 ps_format_delta_time(ps_temp, state->start_time, &elapsed),
-                state->smtp_client_addr, printable(read_buf, '?'));
+                PS_CLIENT_ADDR_PORT(state), printable(read_buf, '?'));
        PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_PREGR_FAIL);
        switch (ps_pregr_action) {
        case PS_ACT_DROP:
@@ -228,7 +228,7 @@ static void ps_early_dnsbl_event(int unused_event, char *context)
     PS_STATE *state = (PS_STATE *) context;
 
     if (msg_verbose)
-       msg_info("%s: notify %s:%s", myname, PS_CLIENT_ADDR_PORT(state));
+       msg_info("%s: notify [%s]:%s", myname, PS_CLIENT_ADDR_PORT(state));
 
     /*
      * Terminate the greet delay if we're just waiting for DNSBL lookup to
index 263a85020e3c252d7ae7d8899e41722aa81d2486..f077a57e6042fffe0a1ef5d0dc4a5038a0b193dd 100644 (file)
@@ -104,8 +104,8 @@ void    ps_conclude(PS_STATE *state)
     if ((state->flags & PS_STATE_MASK_ANY_PASS) != 0
        && (state->flags & PS_STATE_MASK_ANY_PASS) ==
        PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_MASK_ANY_TODO))
-       msg_info("PASS %s %s", (state->flags & PS_STATE_FLAG_NEW) == 0 ?
-                "OLD" : "NEW", state->smtp_client_addr);
+       msg_info("PASS %s [%s]:%s", (state->flags & PS_STATE_FLAG_NEW) == 0 ?
+                "OLD" : "NEW", PS_CLIENT_ADDR_PORT(state));
 
     /*
      * Update the postscreen cache. This still supports a scenario where a
@@ -128,7 +128,7 @@ void    ps_conclude(PS_STATE *state)
            (void) ps_send_reply(vstream_fileno(state->smtp_client_stream),
                           state->smtp_client_addr, state->smtp_client_port,
                                 state->final_reply);
-       msg_info("DISCONNECT %s", state->smtp_client_addr);
+       msg_info("DISCONNECT [%s]:%s", PS_CLIENT_ADDR_PORT(state));
        ps_free_session_state(state);
     }
 }
@@ -148,9 +148,9 @@ void    ps_hangup_event(PS_STATE *state)
      * phase.
      */
     state->flags |= PS_STATE_FLAG_HANGUP;
-    msg_info("HANGUP after %s from %s in %s",
+    msg_info("HANGUP after %s from [%s]:%s in %s",
             ps_format_delta_time(ps_temp, state->start_time, &elapsed),
-            state->smtp_client_addr, state->test_name);
+            PS_CLIENT_ADDR_PORT(state), state->test_name);
     state->flags |= PS_STATE_FLAG_NOFORWARD;
     ps_conclude(state);
 }
index 5b8fc1f222e4866cefe4ab80aa9457c014cb279c..9a47e4fe839195642546e712f896add359659f1d 100644 (file)
@@ -78,7 +78,7 @@ int     ps_send_reply(int smtp_client_fd, const char *smtp_client_addr,
     int     ret;
 
     if (msg_verbose)
-       msg_info("> %s:%s: %.*s", smtp_client_addr, smtp_client_port,
+       msg_info("> [%s]:%s: %.*s", smtp_client_addr, smtp_client_port,
                 (int) strlen(text) - 2, text);
 
     /*
@@ -88,7 +88,7 @@ int     ps_send_reply(int smtp_client_fd, const char *smtp_client_addr,
     ret = (write_buf(smtp_client_fd, text, strlen(text),
                     PS_SEND_TEXT_TIMEOUT) < 0);
     if (ret != 0 && errno != EPIPE)
-       msg_warn("write %s:%s: %m", smtp_client_addr, smtp_client_port);
+       msg_warn("write [%s]:%s: %m", smtp_client_addr, smtp_client_port);
     return (ret);
 }
 
@@ -100,7 +100,7 @@ static void ps_send_socket_close_event(int event, char *context)
     PS_STATE *state = (PS_STATE *) context;
 
     if (msg_verbose > 1)
-       msg_info("%s: sq=%d cq=%d event %d on send socket %d from %s:%s",
+       msg_info("%s: sq=%d cq=%d event %d on send socket %d from [%s]:%s",
                 myname, ps_post_queue_length, ps_check_queue_length,
                 event, state->smtp_server_fd, state->smtp_client_addr,
                 state->smtp_client_port);
@@ -128,7 +128,7 @@ void    ps_send_socket(PS_STATE *state)
     int     window_size;
 
     if (msg_verbose > 1)
-       msg_info("%s: sq=%d cq=%d send socket %d from %s:%s",
+       msg_info("%s: sq=%d cq=%d send socket %d from [%s]:%s",
                 myname, ps_post_queue_length, ps_check_queue_length,
                 vstream_fileno(state->smtp_client_stream),
                 state->smtp_client_addr, state->smtp_client_port);
index f3d6c42679f01a6255d981cdf7e5e2736ca26e39..c05d1fe5c56cc9ef73c89bd3cf4fe45530b213dd 100644 (file)
@@ -321,9 +321,9 @@ static int ps_rcpt_cmd(PS_STATE *state, char *args)
     if ((addr = ps_extract_addr(ps_temp, colon + 1)) == 0)
        return (PS_SEND_REPLY(state,
                              "501 5.1.3 Bad recipient address syntax\r\n"));
-    msg_info("NOQUEUE: reject: RCPT from [%s]: %.*s; "
+    msg_info("NOQUEUE: reject: RCPT from [%s]:%s: %.*s; "
             "from=<%s>, to=<%s>, proto=%s, helo=<%s>",
-            state->smtp_client_addr,
+            PS_CLIENT_ADDR_PORT(state),
             (int) strlen(state->rcpt_reply) - 2, state->rcpt_reply,
             state->sender, addr, state->protocol,
             state->helo_name ? state->helo_name : "");
@@ -428,13 +428,13 @@ static void ps_smtpd_time_event(int event, char *context)
     PS_STATE *state = (PS_STATE *) context;
 
     if (msg_verbose > 1)
-       msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from %s:%s flags=%s",
+       msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
                 myname, ps_post_queue_length, ps_check_queue_length,
                 event, vstream_fileno(state->smtp_client_stream),
                 state->smtp_client_addr, state->smtp_client_port,
                 ps_print_state_flags(state->flags, myname));
 
-    msg_info("COMMAND TIME LIMIT from %s", state->smtp_client_addr);
+    msg_info("COMMAND TIME LIMIT from [%s]:%s", PS_CLIENT_ADDR_PORT(state));
     PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event,
                                      ps_smtpd_timeout_reply);
 }
@@ -499,7 +499,7 @@ static void ps_smtpd_read_event(int event, char *context)
     int     write_stat;
 
     if (msg_verbose > 1)
-       msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from %s:%s flags=%s",
+       msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
                 myname, ps_post_queue_length, ps_check_queue_length,
                 event, vstream_fileno(state->smtp_client_stream),
                 state->smtp_client_addr, state->smtp_client_port,
@@ -543,8 +543,8 @@ static void ps_smtpd_read_event(int event, char *context)
             */
            if (state->read_state == PS_SMTPD_CMD_ST_ANY
                && VSTRING_LEN(state->cmd_buffer) >= var_line_limit) {
-               msg_info("COMMAND LENGTH LIMIT from %s",
-                        state->smtp_client_addr);
+               msg_info("COMMAND LENGTH LIMIT from [%s]:%s",
+                        PS_CLIENT_ADDR_PORT(state));
                PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event,
                                                  ps_smtpd_421_reply);
                return;
@@ -580,7 +580,8 @@ static void ps_smtpd_read_event(int event, char *context)
            if (ch == '\n') {
                if ((state->flags & PS_STATE_MASK_BARLF_TODO_SKIP)
                    == PS_STATE_FLAG_BARLF_TODO) {
-                   msg_info("BARE NEWLINE from %s", state->smtp_client_addr);
+                   msg_info("BARE NEWLINE from [%s]:%s",
+                            PS_CLIENT_ADDR_PORT(state));
                    PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BARLF_FAIL);
                    PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_BARLF_PASS);
                    state->barlf_stamp = PS_TIME_STAMP_DISABLED;        /* XXX */
@@ -644,7 +645,7 @@ static void ps_smtpd_read_event(int event, char *context)
         */
        cmd_buffer_ptr = vstring_str(state->cmd_buffer);
        if (msg_verbose)
-           msg_info("< %s:%s: %s", state->smtp_client_addr,
+           msg_info("< [%s]:%s: %s", state->smtp_client_addr,
                     state->smtp_client_port, cmd_buffer_ptr);
 
        /* Parse the command name. */
@@ -668,8 +669,8 @@ static void ps_smtpd_read_event(int event, char *context)
                || (*var_ps_forbid_cmds
                    && string_list_match(ps_forbid_cmds, command)))) {
            printable(command, '?');
-           msg_info("NON-SMTP COMMAND from %s %.100s",
-                    state->smtp_client_addr, command);
+           msg_info("NON-SMTP COMMAND from [%s]:%s %.100s",
+                    PS_CLIENT_ADDR_PORT(state), command);
            PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_NSMTP_FAIL);
            PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_NSMTP_PASS);
            state->nsmtp_stamp = PS_TIME_STAMP_DISABLED;        /* XXX */
@@ -703,8 +704,8 @@ static void ps_smtpd_read_event(int event, char *context)
        if ((state->flags & PS_STATE_MASK_PIPEL_TODO_SKIP)
            == PS_STATE_FLAG_PIPEL_TODO && !PS_SMTPD_BUFFER_EMPTY(state)) {
            printable(command, '?');
-           msg_info("COMMAND PIPELINING from %s after %.100s",
-                    state->smtp_client_addr, command);
+           msg_info("COMMAND PIPELINING from [%s]:%s after %.100s",
+                    PS_CLIENT_ADDR_PORT(state), command);
            PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_PIPEL_FAIL);
            PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_PIPEL_PASS);
            state->pipel_stamp = PS_TIME_STAMP_DISABLED;        /* XXX */
@@ -766,7 +767,8 @@ static void ps_smtpd_read_event(int event, char *context)
        /* Command COUNT limit test. */
        if (++state->command_count > var_ps_cmd_count
            && cmdp->action != ps_quit_cmd) {
-           msg_info("COMMAND COUNT LIMIT from %s", state->smtp_client_addr);
+           msg_info("COMMAND COUNT LIMIT from [%s]:%s",
+                    PS_CLIENT_ADDR_PORT(state));
            PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event,
                                              ps_smtpd_421_reply);
            return;
index 740c024544133be7c4e74d4a608980819966cfd8..729800494380fd2e62c17b1f31c3e683f29772ab 100644 (file)
 #include <msg.h>
 #include <mymalloc.h>
 #include <name_mask.h>
+#include <htable.h>
 
 /* Global library. */
 
@@ -143,6 +144,7 @@ PS_STATE *ps_new_session_state(VSTREAM *stream,
                                       const char *port)
 {
     PS_STATE *state;
+    HTABLE_INFO *ht;
 
     state = (PS_STATE *) mymalloc(sizeof(*state));
     PS_INIT_TESTS(state);
@@ -171,6 +173,15 @@ PS_STATE *ps_new_session_state(VSTREAM *stream,
        msg_info("entering STRESS mode with %d connections",
                 ps_check_queue_length);
     }
+
+    /*
+     * Update the per-client session count.
+     */
+    if ((ht = htable_locate(ps_client_concurrency, addr)) == 0)
+       ht = htable_enter(ps_client_concurrency, addr, (char *) 0);
+    ht->value += 1;
+    state->client_concurrency = (int) ht->value;
+
     return (state);
 }
 
@@ -178,6 +189,18 @@ PS_STATE *ps_new_session_state(VSTREAM *stream,
 
 void    ps_free_session_state(PS_STATE *state)
 {
+    const char *myname = "ps_free_session_state";
+    HTABLE_INFO *ht;
+
+    /*
+     * Update the per-client session count.
+     */
+    if ((ht = htable_locate(ps_client_concurrency, state->smtp_client_addr)) == 0)
+       msg_panic("%s: unknown client address: %s", 
+                 myname, state->smtp_client_addr);
+    if (--(ht->value) == 0)
+       htable_delete(ps_client_concurrency, state->smtp_client_addr, (void (*) (char *)) 0);
+
     if (state->smtp_client_stream != 0) {
        event_server_disconnect(state->smtp_client_stream);
        ps_check_queue_length--;
index a281d4a502968a385ea67e077c68943d6ac51eb3..3ba7adc7637c4287f510d2cf637653e56016617a 100644 (file)
@@ -156,7 +156,6 @@ void    ps_parse_tests(PS_STATE *state,
                               const char *stamp_str,
                               time_t time_value)
 {
-    const char *myname = "ps_parse_tests";
     unsigned long pregr_stamp;
     unsigned long dnsbl_stamp;
     unsigned long pipel_stamp;
index b07f74fdb863f66cd3b7bb172cebc6bae4252e9b..69c6698125f74361d1fbf95ff42bdf12fa7ca803 100644 (file)
@@ -33,7 +33,7 @@ SRCS  = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
        allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
        upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \
        unix_pass_fd_fix.c dict_cache.c valid_utf_8.c dict_thash.c \
-       ip_match.c ip_lmatch.c
+       ip_match.c
 OBJS   = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
        attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -68,7 +68,7 @@ OBJS  = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
        upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \
        unix_pass_fd_fix.o dict_cache.o valid_utf_8.o dict_thash.o \
-       ip_match.o ip_lmatch.o
+       ip_match.o
 HDRS   = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
        dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@@ -89,7 +89,7 @@ HDRS  = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        username.h valid_hostname.h vbuf.h vbuf_print.h vstream.h vstring.h \
        vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \
        edit_file.h dict_cache.h dict_thash.h \
-       ip_match.h ip_lmatch.h
+       ip_match.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c test_send_fd test_recv_fd
 DEFS   = -I. -D$(SYSTYPE)
@@ -107,7 +107,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
        attr_scan0 host_port attr_scan_plain attr_print_plain htable \
        unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
        myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
-       test_send_fd test_recv_fd valid_utf_8 ip_match ip_lmatch
+       test_send_fd test_recv_fd valid_utf_8 ip_match
 
 LIB_DIR        = ../../lib
 INC_DIR        = ../../include
@@ -427,16 +427,11 @@ ip_match: $(LIB)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
        mv junk $@.o
 
-ip_lmatch: $(LIB)
-       mv $@.o junk
-       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
-       mv junk $@.o
-
 tests: valid_hostname_test mac_expand_test dict_test unescape_test \
        hex_quote_test ctable_test inet_addr_list_test base64_code_test \
        attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
        dict_cidr_test attr_scan_plain_test htable_test hex_code_test \
-       myaddrinfo_test format_tv_test ip_match_test ip_lmatch_test
+       myaddrinfo_test format_tv_test ip_match_test
 
 root_tests:
 
@@ -563,11 +558,6 @@ ip_match_test: ip_match ip_match.in ip_match.ref
        diff ip_match.ref ip_match.tmp
        rm -f ip_match.tmp
 
-ip_lmatch_test: ip_lmatch ip_lmatch.in ip_lmatch.ref
-       ./ip_lmatch <ip_lmatch.in >ip_lmatch.tmp
-       diff ip_lmatch.ref ip_lmatch.tmp
-       rm -f ip_lmatch.tmp
-
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -1214,13 +1204,6 @@ ip_match.o: mymalloc.h
 ip_match.o: sys_defs.h
 ip_match.o: vbuf.h
 ip_match.o: vstring.h
-ip_lmatch.o: ip_lmatch.c
-ip_lmatch.o: ip_lmatch.h
-ip_lmatch.o: msg.h
-ip_lmatch.o: mymalloc.h
-ip_lmatch.o: sys_defs.h
-ip_lmatch.o: vbuf.h
-ip_lmatch.o: vstring.h
 killme_after.o: killme_after.c
 killme_after.o: killme_after.h
 killme_after.o: sys_defs.h
diff --git a/postfix/src/util/ip_lmatch.c b/postfix/src/util/ip_lmatch.c
deleted file mode 100644 (file)
index 70dc1ec..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*++
-/* NAME
-/*     ip_lmatch 3
-/* SUMMARY
-/*     lazy IP address pattern matching
-/* SYNOPSIS
-/*     #include <ip_lmatch.h>
-/*
-/*     int     ip_lmatch(pattern, addr, why)
-/*     char    *pattern;
-/*     const char *addr;
-/*     VSTRING **why;
-/* DESCRIPTION
-/*     This module supports IP address pattern matching. See below
-/*     for a description of the supported address pattern syntax.
-/*
-/*     This version optimizes for implementation convenience.  The
-/*     lazy parser stops as soon as the address does not match the
-/*     pattern. This results in a poor user interface: a pattern
-/*     syntax error at the end will be reported ONLY when an address
-/*     matches the entire pattern before the syntax error.
-/*
-/*     Use the ip_match() module for an implementation that has
-/*     separate parsing and matching stages. That implementation
-/*     reports a syntax error immediately, and provides faster
-/*     matching at the cost of a more complex programming interface.
-/*
-/*     ip_lmatch_parse() matches the address bytes while parsing
-/*     the pattern, and terminates as soon as a non-match or syntax
-/*     error is found.  The result is -1 in case of syntax error,
-/*     0 in case of no match, 1 in case of a match.
-/*
-/*     Arguments
-/* .IP addr
-/*     Network address in printable form.
-/* .IP pattern
-/*     Address pattern. This argument may be modified.
-/* .IP why
-/*     Pointer to storage for error reports (result value -1). If
-/*     the target is a null pointer, ip_lmatch() will allocate a
-/*     buffer that should be freed by the application.
-/* IPV4 PATTERN SYNTAX
-/* .ad
-/* .fi
-/*     An IPv4 address pattern has four fields separated by ".".
-/*     Each field is either a decimal number, or a sequence inside
-/*     "[]" that contains one or more comma-separated decimal
-/*     numbers or number..number ranges.
-/*
-/*     Examples of patterns are 1.2.3.4 (matches itself, as one
-/*     would expect) and 1.2.3.[2,4,6..8] (matches 1.2.3.2, 1.2.3.4,
-/*     1.2.3.6, 1.2.3.7, 1.2.3.8).
-/*
-/*     Thus, any pattern field can be a sequence inside "[]", but
-/*     a "[]" sequence cannot span multiple address fields, and
-/*     a pattern field cannot contain both a number and a "[]"
-/*     sequence at the same time.
-/*
-/*     This means that the pattern 1.2.[3.4] is not valid (the
-/*     sequence [3.4] cannot span two address fields) and the
-/*     pattern 1.2.3.3[6..9] is also not valid (the last field
-/*     cannot be both number 3 and sequence [6..9] at the same
-/*     time).
-/*
-/*     The syntax for IPv4 patterns is as follows:
-/*
-/* .in +5
-/*     v4pattern = v4field "." v4field "." v4field "." v4field
-/* .br
-/*     v4field = v4octet | "[" v4sequence "]
-/* .br
-/*     v4octet = any decimal number in the range 0 through 255
-/* .br
-/*     v4sequence = v4seq_member | v4sequence "," v4seq_member
-/* .br
-/*     v4seq_member = v4octet | v4octet ".." v4octet
-/* .in
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this
-/*     software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <string.h>
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-#include <vstring.h>
-#include <myaddrinfo.h>
-#include <ip_lmatch.h>
-
- /*
-  * Token values.
-  */
-#define IP_LMATCH_CODE_OPEN    '['     /* start of set */
-#define IP_LMATCH_CODE_CLOSE   ']'     /* end of set */
-#define IP_LMATCH_CODE_OVAL    'N'     /* octet value */
-#define IP_LMATCH_CODE_EOF     '\0'    /* oops */
-#define IP_LMATCH_CODE_ERR     256     /* oops */
-
- /*
-  * Address length is protocol dependent. Find out how large our address byte
-  * strings should be.
-  */
-#ifdef HAS_IPV6
-#define IP_LMATCH_ABYTES       MAI_V6ADDR_BYTES
-#else
-#define IP_LMATCH_ABYTES       MAI_V4ADDR_BYTES
-#endif
-
- /*
-  * SLMs.
-  */
-#define STR    vstring_str
-#define LEN    VSTRING_LEN
-
-/* ip_lmatch_next_token - carve out the next token from user input */
-
-static int ip_lmatch_next_token(char **pstart, char **psaved_start, int *poval)
-{
-    unsigned char *cp;
-    unsigned char *next;
-    int     oval;
-
-    /*
-     * Return a value-less token (i.e. a literal, error, or EOF.
-     */
-#define IP_LMATCH_RETURN_TOK(next, type) \
-    do { *pstart = (char *) (next); return (type); } while (0)
-
-    /*
-     * Return a token that contains an IPv4 address octet value.
-     */
-#define IP_LMATCH_RETURN_TOK_OVAL(next, oval) do { \
-       *poval = (oval); IP_LMATCH_RETURN_TOK((next), IP_LMATCH_CODE_OVAL); \
-    } while (0)
-
-    /*
-     * Light-weight tokenizer. Each result is an IPv4 address octet value, a
-     * literal character value, error, or EOF.
-     */
-    *psaved_start = *pstart;
-    cp = (unsigned char *) *pstart;
-    if (ISDIGIT(*cp)) {
-       oval = *cp - '0';
-       for (next = cp + 1; ISDIGIT(*next); next++) {
-           oval *= 10;
-           oval += *next - '0';
-           if (oval > 255)
-               IP_LMATCH_RETURN_TOK(next + 1, IP_LMATCH_CODE_ERR);
-       }
-       IP_LMATCH_RETURN_TOK_OVAL(next, oval);
-    } else {
-       IP_LMATCH_RETURN_TOK(*cp ? cp + 1 : cp, *cp);
-    }
-}
-
-/* ip_lmatch_print_parse_error - report parsing error in context */
-
-static void PRINTFLIKE(5, 6) ip_lmatch_print_parse_error(VSTRING **why,
-                                                                char *start,
-                                                                char *here,
-                                                                char *next,
-                                                       const char *fmt,...)
-{
-    va_list ap;
-    int     start_width;
-    int     here_width;
-
-    /*
-     * On-the-fly allocation.
-     */
-    if (*why == 0)
-       *why = vstring_alloc(20);
-
-    /*
-     * Format the error type.
-     */
-    va_start(ap, fmt);
-    vstring_vsprintf(*why, fmt, ap);
-    va_end(ap);
-
-    /*
-     * Format the error context. The syntax is complex enough that it is
-     * worth the effort to precisely indicate what input is in error.
-     * 
-     * XXX Workaround for %.*s to avoid output when a zero width is specified.
-     */
-#define IP_LMATCH_NO_ERROR_CONTEXT (char *) 0, (char *) 0, (char *) 0
-
-    if (start != 0) {
-       start_width = here - start;
-       here_width = next - here;
-       vstring_sprintf_append(*why, " at \"%.*s>%.*s<%s\"",
-                              start_width, start_width == 0 ? "" : start,
-                            here_width, here_width == 0 ? "" : here, next);
-    }
-}
-
-/* ip_lmatch - match an address pattern */
-
-int     ip_lmatch(char *pattern, const char *addr, VSTRING **why)
-{
-    const char *myname = "ip_lmatch";
-    char    addr_bytes[IP_LMATCH_ABYTES];
-    const unsigned char *ap;
-    int     octet_count;
-    char   *saved_cp;
-    char   *cp;
-    int     token_type;
-    int     look_ahead;
-    int     oval;
-    int     saved_oval;
-    int     matched;
-
-    /*
-     * For now, IPv4 support only. Use different parser loops for IPv4 and
-     * IPv6.
-     */
-    switch (inet_pton(AF_INET, addr, addr_bytes)) {
-    case -1:
-       msg_fatal("%s: address conversion error: %m", myname);
-    case 0:
-       msg_warn("%s: unexpected address form: %s", myname, addr);
-       return (0);
-    }
-
-    /*
-     * Simplify this if we change to {} for "octet set" notation.
-     */
-#define FIND_TERMINATOR(start, cp) do { \
-       int _level = 1; \
-       for (cp = (start) ; *cp; cp++) { \
-           if (*cp == '[') _level++; \
-           if (*cp != ']') continue; \
-           if (--_level == 0) break; \
-       } \
-    } while (0)
-
-    /*
-     * Strip [] around the entire pattern.
-     */
-    if (*pattern == '[') {
-       FIND_TERMINATOR(pattern, cp);
-       if (cp[0] == 0) {
-           ip_lmatch_print_parse_error(why, IP_LMATCH_NO_ERROR_CONTEXT,
-                                       "missing \"]\" character");
-           return (-1);
-       }
-       if (cp[1] == 0) {
-           *cp = 0;
-           pattern += 1;
-       }
-    }
-
-    /*
-     * Sanity check. In this case we can't show any error context.
-     */
-    if (*pattern == 0) {
-       ip_lmatch_print_parse_error(why, IP_LMATCH_NO_ERROR_CONTEXT,
-                                   "empty address pattern");
-       return (-1);
-    }
-
-    /*
-     * Simple on-the-fly pattern matching.
-     */
-    octet_count = 0;
-    cp = pattern;
-
-    /*
-     * Require four address fields separated by ".", each field containing a
-     * numeric octet value or a sequence inside []. The loop head has no test
-     * and does not step the loop variable. The tokenizer advances the loop
-     * variable, and the loop termination logic is inside the loop.
-     */
-    for (ap = (const unsigned char *) addr_bytes; /* void */ ; ap++) {
-       switch (token_type = ip_lmatch_next_token(&cp, &saved_cp, &oval)) {
-
-           /*
-            * Numeric address field.
-            */
-       case IP_LMATCH_CODE_OVAL:
-           if (*ap == oval)
-               break;
-           return (0);
-
-           /*
-            * Wild-card address field.
-            */
-       case IP_LMATCH_CODE_OPEN:
-           matched = 0;
-           /* Require comma-separated numbers or numeric ranges. */
-           for (;;) {
-               token_type = ip_lmatch_next_token(&cp, &saved_cp, &oval);
-               if (token_type == IP_LMATCH_CODE_OVAL) {
-                   saved_oval = oval;
-                   look_ahead = ip_lmatch_next_token(&cp, &saved_cp, &oval);
-                   /* Numeric range. */
-                   if (look_ahead == '.') {
-                       /* Brute-force parsing. */
-                       if (ip_lmatch_next_token(&cp, &saved_cp, &oval) == '.'
-                           && ip_lmatch_next_token(&cp, &saved_cp, &oval)
-                           == IP_LMATCH_CODE_OVAL
-                           && saved_oval <= oval) {
-                           if (!matched)
-                               matched = (*ap >= saved_oval && *ap <= oval);
-                           look_ahead =
-                               ip_lmatch_next_token(&cp, &saved_cp, &oval);
-                       } else {
-                           ip_lmatch_print_parse_error(why, pattern,
-                                                       saved_cp, cp,
-                                                    "numeric range error");
-                           return (-1);
-                       }
-                   }
-                   /* Single number. */
-                   else {
-                       if (!matched)
-                           matched = (*ap == oval);
-                   }
-                   /* Require "," or end-of-wildcard. */
-                   token_type = look_ahead;
-                   if (token_type == ',') {
-                       continue;
-                   } else if (token_type == IP_LMATCH_CODE_CLOSE) {
-                       break;
-                   } else {
-                       ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
-                                                   "need \",\" or \"%c\"",
-                                                   IP_LMATCH_CODE_CLOSE);
-                       return (-1);
-                   }
-               } else {
-                   ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
-                                             "need decimal number 0..255");
-                   return (-1);
-               }
-           }
-           if (matched == 0)
-               return (0);
-           break;
-
-           /*
-            * Invalid field.
-            */
-       default:
-           ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
-                                    "need decimal number 0..255 or \"%c\"",
-                                       IP_LMATCH_CODE_OPEN);
-           return (-1);
-       }
-       octet_count += 1;
-
-       /*
-        * Require four address fields. Not one more, not one less.
-        */
-       if (octet_count == 4) {
-           if (*cp != 0) {
-               (void) ip_lmatch_next_token(&cp, &saved_cp, &oval);
-               ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
-                                           "garbage after pattern");
-               return (-1);
-           }
-           return (1);
-       }
-
-       /*
-        * Require "." before the next address field.
-        */
-       if (ip_lmatch_next_token(&cp, &saved_cp, &oval) != '.') {
-           ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
-                                       "need \".\"");
-           return (-1);
-       }
-    }
-}
-
-#ifdef TEST
-
- /*
-  * Dummy main program for regression tests.
-  */
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <vstream.h>
-#include <vstring_vstream.h>
-#include <stringops.h>
-
-int     main(int argc, char **argv)
-{
-    VSTRING *why = vstring_alloc(100);
-    VSTRING *line_buf = vstring_alloc(100);
-    char   *bufp;
-    char   *user_pattern;
-    char   *user_address;
-    int     echo_input = !isatty(0);
-    int     match_status;
-
-    /*
-     * Iterate over the input stream. The input format is a pattern, followed
-     * by addresses to match against.
-     */
-    while (vstring_fgets_nonl(line_buf, VSTREAM_IN)) {
-       bufp = STR(line_buf);
-       if (echo_input) {
-           vstream_printf("> %s\n", bufp);
-           vstream_fflush(VSTREAM_OUT);
-       }
-       if (*bufp == '#')
-           continue;
-       if ((user_pattern = mystrtok(&bufp, " \t")) == 0)
-           continue;
-
-       /*
-        * Match the patterns.
-        */
-       while ((user_address = mystrtok(&bufp, " \t")) != 0) {
-           match_status = ip_lmatch(user_pattern, user_address, &why);
-           if (match_status < 0) {
-               vstream_printf("Error: %s\n", STR(why));
-           } else {
-               vstream_printf("Match %s: %s\n", user_address,
-                              match_status ? "yes" : "no");
-           }
-           vstream_fflush(VSTREAM_OUT);
-       }
-    }
-    vstring_free(line_buf);
-    vstring_free(why);
-    exit(0);
-}
-
-#endif
diff --git a/postfix/src/util/ip_lmatch.h b/postfix/src/util/ip_lmatch.h
deleted file mode 100644 (file)
index 788956f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _IP_LMATCH_H_INCLUDED_
-#define _IP_LMATCH_H_INCLUDED_
-
-/*++
-/* NAME
-/*     ip_lmatch 3h
-/* SUMMARY
-/*     lazy IP address pattern matching
-/* SYNOPSIS
-/*     #include <ip_lmatch.h>
-/* DESCRIPTION
-/* .nf
-
- /*
-  * Utility library.
-  */
-#include <vstring.h>
-
- /*
-  * External interface.
-  */
-extern int ip_lmatch(char *, const char *, VSTRING **);
-
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-#endif
diff --git a/postfix/src/util/ip_lmatch.in b/postfix/src/util/ip_lmatch.in
deleted file mode 100644 (file)
index 9b7aba3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-1.2.3.4                1.2.3.4
-1.2.300.4      1.2.3.4
-1.2.3.         1.2.3.4
-1.2.3          1.2.3.4
-a              1.2.3.4
-1.2.3,4                1.2.3.4
-1.2.[3].4      1.2.3.4
-1.2.[].4       1.2.3.4
-1.2.[.4                1.2.3.4
-1.2.].4                1.2.3.4
-1.2.[1..127,128..255].5        1.2.3.4
-1.2.[1-255].5  1.2.3.4
-1.2.[1..127.128..255].5        1.2.3.4
-1.2.3.[4]      1.2.3.4
-1.2.3.[4..1]   1.2.3.4
-1.2.3.[4.1]    1.2.3.4
-1.2.3.[4.x]    1.2.3.4
-1.2.3.[x]      1.2.3.4
-1.2.3.4x       1.2.3.4
-1.2.[3..11].5  1.2.3.5 1.2.2.5 1.2.11.5 1.2.12.5  1.2.11.6
-1.2.[3,5,7,9,11].5     1.2.3.5 1.2.2.5 1.2.4.5 1.2.11.5 1.2.12.5  1.2.11.6
diff --git a/postfix/src/util/ip_lmatch.ref b/postfix/src/util/ip_lmatch.ref
deleted file mode 100644 (file)
index d8431bd..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-> 1.2.3.4              1.2.3.4
-Match 1.2.3.4: yes
-> 1.2.300.4    1.2.3.4
-Error: need decimal number 0..255 or "[" at "1.2.>300<.4"
-> 1.2.3.               1.2.3.4
-Error: need decimal number 0..255 or "[" at "1.2.3.><"
-> 1.2.3                1.2.3.4
-Error: need "." at "1.2.3><"
-> a            1.2.3.4
-Error: need decimal number 0..255 or "[" at ">a<"
-> 1.2.3,4              1.2.3.4
-Error: need "." at "1.2.3>,<4"
-> 1.2.[3].4    1.2.3.4
-Match 1.2.3.4: yes
-> 1.2.[].4     1.2.3.4
-Error: need decimal number 0..255 at "1.2.[>]<.4"
-> 1.2.[.4              1.2.3.4
-Error: need decimal number 0..255 at "1.2.[>.<4"
-> 1.2.].4              1.2.3.4
-Error: need decimal number 0..255 or "[" at "1.2.>]<.4"
-> 1.2.[1..127,128..255].5      1.2.3.4
-Match 1.2.3.4: no
-> 1.2.[1-255].5        1.2.3.4
-Error: need "," or "]" at "1.2.[1>-<255].5"
-> 1.2.[1..127.128..255].5      1.2.3.4
-Error: need "," or "]" at "1.2.[1..127>.<128..255].5"
-> 1.2.3.[4]    1.2.3.4
-Match 1.2.3.4: yes
-> 1.2.3.[4..1] 1.2.3.4
-Error: numeric range error at "1.2.3.[4..>1<]"
-> 1.2.3.[4.1]  1.2.3.4
-Error: numeric range error at "1.2.3.[4.>1<]"
-> 1.2.3.[4.x]  1.2.3.4
-Error: numeric range error at "1.2.3.[4.>x<]"
-> 1.2.3.[x]    1.2.3.4
-Error: need decimal number 0..255 at "1.2.3.[>x<]"
-> 1.2.3.4x     1.2.3.4
-Error: garbage after pattern at "1.2.3.4>x<"
-> 1.2.[3..11].5        1.2.3.5 1.2.2.5 1.2.11.5 1.2.12.5  1.2.11.6
-Match 1.2.3.5: yes
-Match 1.2.2.5: no
-Match 1.2.11.5: yes
-Match 1.2.12.5: no
-Match 1.2.11.6: no
-> 1.2.[3,5,7,9,11].5   1.2.3.5 1.2.2.5 1.2.4.5 1.2.11.5 1.2.12.5  1.2.11.6
-Match 1.2.3.5: yes
-Match 1.2.2.5: no
-Match 1.2.4.5: no
-Match 1.2.11.5: yes
-Match 1.2.12.5: no
-Match 1.2.11.6: no
index 17d1db29c6843eca98b0f395c77e4be8e2cc8c1b..eb9333481449546cd94edf410a066e6c15ddd1f0 100644 (file)
@@ -24,8 +24,8 @@
 /*     This module supports IP address pattern matching. See below
 /*     for a description of the supported address pattern syntax.
 /*
-/*     This implementation aims to minimize the cost of translating
-/*     the pattern to internal form, while still providing good
+/*     This implementation aims to minimize the cost of encoding
+/*     the pattern in internal form, while still providing good
 /*     matching performance in the typical case.   The first byte
 /*     of an encoded pattern specifies the expected address family
 /*     (for example, AF_INET); other details of the encoding are
@@ -357,8 +357,8 @@ int     ip_match_execute(const char *byte_codes, const char *addr_bytes)
 static int ip_match_next_token(char **pstart, char **psaved_start, int *poval)
 {
     unsigned char *cp;
-    unsigned char *next;
-    int     oval;
+    int     oval;                      /* octet value */
+    int     type;                      /* token value */
 
     /*
      * Return a literal, error, or EOF token. Update the read pointer to the
@@ -370,8 +370,8 @@ static int ip_match_next_token(char **pstart, char **psaved_start, int *poval)
     /*
      * Return a token that contains an IPv4 address octet value.
      */
-#define IP_MATCH_RETURN_TOK_OVAL(next, oval) do { \
-       *poval = (oval); IP_MATCH_RETURN_TOK((next), IP_MATCH_CODE_OVAL); \
+#define IP_MATCH_RETURN_TOK_VAL(next, type, oval) do { \
+       *poval = (oval); IP_MATCH_RETURN_TOK((next), type); \
     } while (0)
 
     /*
@@ -382,13 +382,14 @@ static int ip_match_next_token(char **pstart, char **psaved_start, int *poval)
     cp = (unsigned char *) *pstart;
     if (ISDIGIT(*cp)) {
        oval = *cp - '0';
-       for (next = cp + 1; ISDIGIT(*next); next++) {
+       type = IP_MATCH_CODE_OVAL;
+       for (cp += 1; ISDIGIT(*cp); cp++) {
            oval *= 10;
-           oval += *next - '0';
+           oval += *cp - '0';
            if (oval > 255)
-               IP_MATCH_RETURN_TOK(next + 1, IP_MATCH_CODE_ERR);
+               type = IP_MATCH_CODE_ERR;
        }
-       IP_MATCH_RETURN_TOK_OVAL(next, oval);
+       IP_MATCH_RETURN_TOK_VAL(cp, type, oval);
     } else {
        IP_MATCH_RETURN_TOK(*cp ? cp + 1 : cp, *cp);
     }
index 97964fbfbb222b6166ced53fffc0aa3975538443..0aae84b58cfcc72d2e3264ea247cae5f0a8b6d69 100644 (file)
@@ -1,5 +1,6 @@
 1.2.3.4
 1.2.300.4
+1.2.3000.4
 1.2.3.
 1.2.3
 a
index ba75840c5e954ceb012af8dcbe98fcc94de9fe21..3293b10ec9cca67a60bafd0d21f0fb36d50db1c2 100644 (file)
@@ -2,6 +2,8 @@
 Code: 1.2.3.4
 > 1.2.300.4
 Error: need decimal number 0..255 or "[" at "1.2.>300<.4"
+> 1.2.3000.4
+Error: need decimal number 0..255 or "[" at "1.2.>3000<.4"
 > 1.2.3.
 Error: need decimal number 0..255 or "[" at "1.2.3.><"
 > 1.2.3