diff options
Diffstat (limited to 'contrib/bind/bin/named/ns_sort.c')
-rw-r--r-- | contrib/bind/bin/named/ns_sort.c | 414 |
1 files changed, 0 insertions, 414 deletions
diff --git a/contrib/bind/bin/named/ns_sort.c b/contrib/bind/bin/named/ns_sort.c deleted file mode 100644 index 6489c4d..0000000 --- a/contrib/bind/bin/named/ns_sort.c +++ /dev/null @@ -1,414 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_sort.c 4.10 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_sort.c,v 8.8 2001/09/25 04:50:22 marka Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Sorting should really be handled by the resolver, but: - * 1) There are too many brain dead resolvers out there that can't be replaced. - * 2) It would be a pain to individually configure all those resolvers anyway. - * - * Here's the scoop: - * - * To enable address sorting in responses, you need to supply the sortlist - * statement in the config file. The sortlist statement takes an - * address match list and interprets it even more specially than the - * topology statement does. - * - * Each top level statement in the sortlist must itself be an explicit - * address match list with one or two elements. The first element - * (which may be an IP address, an IP prefix, an ACL name or nested - * address match list) of each top level list is checked against the - * source address of the query until a match is found. - * - * Once the source address of the query has been matched, if the top level - * statement contains only one element, the actual primitive element that - * matched the source address is used to select the address in the response - * to move to the beginning of the response. If the statement is a list - * of two elements, then the second element is treated like the address - * match list in a topology statement. Each top level element is assigned - * a distance and the address in the response with the minimum distance is - * moved to the beginning of the response. - * - * In the following example, any queries received from any of the addresses - * of the host itself will get responses preferring addresses on any of - * the locally connected networks. Next most preferred are addresses on - * the 192.168.1/24 network, and after that either the 192.168.2/24 or - * 192.168.3/24 network with no preference shown between these two networks. - * Queries received from a host on the 192.168.1/24 network will prefer - * other addresses on that network to the 192.168.2/24 and 192.168.3/24 - * networks. Queries received from a host on the 192.168.4/24 or the - * 192.168.5/24 network will only prefer other addresses on their - * directly connected networks. - * - * sortlist { - * { - * localhost; - * { - * localnets; - * 192.168.1/24; - * { 192,168.2/24; 192.168.3/24; }; - * }; - * }; - * { - * 192.168.1/24; - * { - * 192.168.1/24; - * { 192.168.2/24; 192.168.3/24; }; - * }; - * }; - * { - * 192.168.2/24; - * { - * 192.168.2/24; - * { 192.168.1/24; 192.168.3/24; }; - * }; - * }; - * { - * 192.168.3/24; - * { - * 192.168.3/24; - * { 192.168.1/24; 192.168.2/24; }; - * }; - * }; - * { - * { 192.168.4/24; 192.168.5/24; }; - * }; - * }; - * - * - * The following example will give reasonable behaviour for the local host - * and hosts on directly connected networks. It is similar to the behavior - * of the address sort in BIND 4.9.x. Responses sent to queries from the - * local host will favor any of the directly connected networks. Responses - * sent to queries from any other hosts on a directly connected network will - * prefer addresses on that same network. Responses to other queries will - * not be sorted. - * - * sortlist { - * { localhost; localnets; }; - * { localnets; }; - * }; - * - * XXX - it wouldb e nice to have an ACL called "source" that matched the - * source address of a query so that a host could be configured to - * automatically prefer itself, and an ACL called "sourcenet", that - * would return the primitive IP match element that matched the source - * address so that you could do: - * { localnets; { sourcenet; { other stuff ...}; }; - * and automatically get similar behaviour to what you get with: - * { localnets; }; - * - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <syslog.h> -#include <resolv.h> -#include <string.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -static int sort_rr(u_char *cp, u_char *eom, int ancount, ip_match_list iml); - -static int ip_match_address_elt(ip_match_list, struct in_addr, - ip_match_element *); - -void -sort_response(u_char *cp, u_char *eom, int ancount, struct sockaddr_in *from) { - struct in_addr address; - struct ip_match_element imelement; - ip_match_element imetl, imematch, imeprimitive; - struct ip_match_list imlist; - ip_match_list iml; - int indirect, matched; - - if (server_options->sortlist == NULL) - return; - - if (from->sin_family != AF_INET) - return; - - address = from->sin_addr; - - for (imetl = server_options->sortlist->first; imetl != NULL; - imetl = imetl->next) { - if (imetl->type == ip_match_indirect) - imematch = imetl->u.indirect.list->first; - else - /* - * allow a bare pattern as a top level statement - * and treat it like {pattern;}; - */ - imematch = imetl; - - switch (imematch->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - imematch->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - imematch->u.indirect.list = local_networks; - indirect = 1; - break; - default: - indirect = 0; - panic("unexpected ime type in ip_match_address()", - NULL); - } - if (indirect) { - imeprimitive = NULL; - matched = ip_match_address_elt(imematch->u.indirect.list, - address, &imeprimitive); - if (matched >= 0) { - if (imematch->flags & IP_MATCH_NEGATE) - /* Don't sort */ - return; - } else - continue; - } else { - if (ina_onnet(address, imematch->u.direct.address, - imematch->u.direct.mask)) { - if (imematch->flags & IP_MATCH_NEGATE) - /* Don't sort */ - return; - else - imeprimitive = imematch; - } else - continue; - } - if (imetl != imematch && imematch->next != NULL) { - /* - * Not a bare pattern at the top level, but a two - * element list - */ - switch (imematch->next->type) { - case ip_match_pattern: - case ip_match_localhost: - case ip_match_localnets: - imelement = *(imematch->next); - imelement.next = NULL; - iml = &imlist; - iml->first = iml->last = &imelement; - break; - case ip_match_indirect: - iml = imematch->next->u.indirect.list; - break; - default: - iml = NULL; - panic("unexpected ime type in ip_match_address()", - NULL); - } - } else if (imeprimitive) { - imelement = *imeprimitive; - imelement.next = NULL; - iml = &imlist; - iml->first = iml->last = &imelement; - } else { - /* Don't sort because we'd just use "any" */ - return; - } - sort_rr(cp, eom, ancount, iml); - break; - } - - return; -} - -static int -sort_rr(u_char *cp, u_char *eom, int ancount, ip_match_list iml) { - int type, class, dlen, n, c, distance, closest = 0; - struct in_addr inaddr; - u_char *rr1 = NULL, *rrbest = NULL, *cpstart; - - rr1 = NULL; - cpstart = cp; - for (c = ancount; c > 0; --c) { - n = dn_skipname(cp, eom); - if (n < 0) - return (1); /* bogus, stop processing */ - cp += n; - if (cp + QFIXEDSZ > eom) - return (1); - GETSHORT(type, cp); - GETSHORT(class, cp); - cp += INT32SZ; - GETSHORT(dlen, cp); - if (dlen > eom - cp) - return (1); /* bogus, stop processing */ - switch (type) { - case T_A: - switch (class) { - case C_IN: - case C_HS: - memcpy((char *)&inaddr, cp, INADDRSZ); - /* Find the address with the minimum distance */ - if (rr1 == NULL) { - rr1 = cp; - rrbest = cp; - closest = distance_of_address(iml, inaddr); - } else { - distance = distance_of_address(iml, inaddr); - if (distance < closest) { - rrbest = cp; - closest = distance; - } - } - break; - } - break; - } - cp += dlen; - } - if (rr1 != rrbest && rr1 != NULL) { - memcpy((char *)&inaddr, rrbest, INADDRSZ); - memcpy(rrbest, rr1, INADDRSZ); - memcpy(rr1, (char *)&inaddr, INADDRSZ); - } - return (0); -} - -/* - * Just like ip_match_address(), but also returns a pointer to the primitive - * element that matched. - */ - -static int -ip_match_address_elt(ip_match_list iml, struct in_addr address, - ip_match_element *imep) { - ip_match_element ime; - int ret; - int indirect; - - INSIST(iml != NULL); - for (ime = iml->first; ime != NULL; ime = ime->next) { - switch (ime->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - ime->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - ime->u.indirect.list = local_networks; - indirect = 1; - break; - default: - indirect = 0; - panic("unexpected ime type in ip_match_address()", - NULL); - } - if (indirect) { - ret = ip_match_address_elt(ime->u.indirect.list, - address, imep); - if (ret >= 0) { - if (ime->flags & IP_MATCH_NEGATE) - ret = (ret) ? 0 : 1; - return (ret); - } - } else { - if (ina_onnet(address, ime->u.direct.address, - ime->u.direct.mask)) { - *imep = ime; - if (ime->flags & IP_MATCH_NEGATE) - return (0); - else - return (1); - } - } - } - return (-1); -} |