+.section "Handling multiple DNS records from a DNS list" "SECThanmuldnsrec"
+A DNS lookup for a &%dnslists%& condition may return more than one DNS record,
+thereby providing more than one IP address. When an item in a &%dnslists%& list
+is followed by &`=`& or &`&&`& and a list of IP addresses, in order to restrict
+the match to specific results from the DNS lookup, there are two ways in which
+the checking can be handled. For example, consider the condition:
+.code
+dnslists = a.b.c=127.0.0.1
+.endd
+What happens if the DNS lookup for the incoming IP address yields both
+127.0.0.1 and 127.0.0.2 by means of two separate DNS records? Is the
+condition true because at least one given value was found, or is it false
+because at least one of the found values was not listed? And how does this
+affect negated conditions? Both possibilities are provided for with the help of
+additional separators &`==`& and &`=&&`&.
+
+.ilist
+If &`=`& or &`&&`& is used, the condition is true if any one of the looked up
+IP addresses matches one of the listed addresses. For the example above, the
+condition is true because 127.0.0.1 matches.
+.next
+If &`==`& or &`=&&`& is used, the condition is true only if every one of the
+looked up IP addresses matches one of the listed addresses. If the condition is
+changed to:
+.code
+dnslists = a.b.c==127.0.0.1
+.endd
+and the DNS lookup yields both 127.0.0.1 and 127.0.0.2, the condition is
+false because 127.0.0.2 is not listed. You would need to have:
+.code
+dnslists = a.b.c==127.0.0.1,127.0.0.2
+.endd
+for the condition to be true.
+.endlist
+
+When &`!`& is used to negate IP address matching, it inverts the result, giving
+the precise opposite of the behaviour above. Thus:
+.ilist
+If &`!=`& or &`!&&`& is used, the condition is true if none of the looked up IP
+addresses matches one of the listed addresses. Consider:
+.code
+dnslists = a.b.c!&0.0.0.1
+.endd
+If the DNS lookup yields both 127.0.0.1 and 127.0.0.2, the condition is
+false because 127.0.0.1 matches.
+.next
+If &`!==`& or &`!=&&`& is used, the condition is true there is at least one
+looked up IP address that does not match. Consider:
+.code
+dnslists = a.b.c!=&0.0.0.1
+.endd
+If the DNS lookup yields both 127.0.0.1 and 127.0.0.2, the condition is
+true, because 127.0.0.2 does not match. You would need to have:
+.code
+dnslists = a.b.c!=&0.0.0.1,0.0.0.2
+.endd
+for the condition to be false.
+.endlist
+When the DNS lookup yields only a single IP address, there is no difference
+between &`=`& and &`==`& and between &`&&`& and &`=&&`&.
+
+
+
+
+.section "Detailed information from merged DNS lists" "SECTmordetinf"
+.cindex "DNS list" "information from merged"
+When the facility for restricting the matching IP values in a DNS list is used,
+the text from the TXT record that is set in &$dnslist_text$& may not reflect
+the true reason for rejection. This happens when lists are merged and the IP
+address in the A record is used to distinguish them; unfortunately there is
+only one TXT record. One way round this is not to use merged lists, but that
+can be inefficient because it requires multiple DNS lookups where one would do
+in the vast majority of cases when the host of interest is not on any of the
+lists.
+
+A less inefficient way of solving this problem is available. If
+two domain names, comma-separated, are given, the second is used first to
+do an initial check, making use of any IP value restrictions that are set.
+If there is a match, the first domain is used, without any IP value
+restrictions, to get the TXT record. As a byproduct of this, there is also
+a check that the IP being tested is indeed on the first list. The first
+domain is the one that is put in &$dnslist_domain$&. For example:
+.code
+reject message = \
+ rejected because $sender_host_address is blacklisted \
+ at $dnslist_domain\n$dnslist_text
+ dnslists = \
+ sbl.spamhaus.org,sbl-xbl.spamhaus.org=127.0.0.2 : \
+ dul.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.10
+.endd
+For the first blacklist item, this starts by doing a lookup in
+&'sbl-xbl.spamhaus.org'& and testing for a 127.0.0.2 return. If there is a
+match, it then looks in &'sbl.spamhaus.org'&, without checking the return
+value, and as long as something is found, it looks for the corresponding TXT
+record. If there is no match in &'sbl-xbl.spamhaus.org'&, nothing more is done.
+The second blacklist item is processed similarly.
+
+If you are interested in more than one merged list, the same list must be
+given several times, but because the results of the DNS lookups are cached,
+the DNS calls themselves are not repeated. For example:
+.code
+reject dnslists = \
+ http.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.2 : \
+ socks.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.3 : \
+ misc.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.4 : \
+ dul.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.10
+.endd
+In this case there is one lookup in &'dnsbl.sorbs.net'&, and if none of the IP
+values matches (or if no record is found), this is the only lookup that is
+done. Only if there is a match is one of the more specific lists consulted.
+
+
+