00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <isc/mem.h>
00025 #include <isc/util.h>
00026
00027 #include <dns/acl.h>
00028 #include <dns/result.h>
00029
00030 #include <named/globals.h>
00031 #include <named/server.h>
00032 #include <named/sortlist.h>
00033
00034 ns_sortlisttype_t
00035 ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr,
00036 const void **argp)
00037 {
00038 unsigned int i;
00039
00040 if (acl == NULL)
00041 goto dont_sort;
00042
00043 for (i = 0; i < acl->length; i++) {
00044
00045
00046
00047
00048 dns_aclelement_t *e = &acl->elements[i];
00049 dns_aclelement_t *try_elt;
00050 dns_aclelement_t *order_elt = NULL;
00051 const dns_aclelement_t *matched_elt = NULL;
00052
00053 if (e->type == dns_aclelementtype_nestedacl) {
00054 dns_acl_t *inner = e->nestedacl;
00055
00056 if (inner->length == 0)
00057 try_elt = e;
00058 else if (inner->length > 2)
00059 goto dont_sort;
00060 else if (inner->elements[0].negative)
00061 goto dont_sort;
00062 else {
00063 try_elt = &inner->elements[0];
00064 if (inner->length == 2)
00065 order_elt = &inner->elements[1];
00066 }
00067 } else {
00068
00069
00070
00071
00072 try_elt = e;
00073 }
00074
00075 if (dns_aclelement_match(clientaddr, NULL, try_elt,
00076 &ns_g_server->aclenv,
00077 &matched_elt)) {
00078 if (order_elt != NULL) {
00079 if (order_elt->type ==
00080 dns_aclelementtype_nestedacl) {
00081 *argp = order_elt->nestedacl;
00082 return (NS_SORTLISTTYPE_2ELEMENT);
00083 } else if (order_elt->type ==
00084 dns_aclelementtype_localhost &&
00085 ns_g_server->aclenv.localhost != NULL) {
00086 *argp = ns_g_server->aclenv.localhost;
00087 return (NS_SORTLISTTYPE_2ELEMENT);
00088 } else if (order_elt->type ==
00089 dns_aclelementtype_localnets &&
00090 ns_g_server->aclenv.localnets != NULL) {
00091 *argp = ns_g_server->aclenv.localnets;
00092 return (NS_SORTLISTTYPE_2ELEMENT);
00093 } else {
00094
00095
00096
00097
00098
00099 *argp = order_elt;
00100 return (NS_SORTLISTTYPE_1ELEMENT);
00101 }
00102 } else {
00103 INSIST(matched_elt != NULL);
00104 *argp = matched_elt;
00105 return (NS_SORTLISTTYPE_1ELEMENT);
00106 }
00107 }
00108 }
00109
00110
00111 dont_sort:
00112 *argp = NULL;
00113 return (NS_SORTLISTTYPE_NONE);
00114 }
00115
00116 int
00117 ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg) {
00118 const dns_acl_t *sortacl = (const dns_acl_t *) arg;
00119 int match;
00120
00121 (void)dns_acl_match(addr, NULL, sortacl,
00122 &ns_g_server->aclenv,
00123 &match, NULL);
00124 if (match > 0)
00125 return (match);
00126 else if (match < 0)
00127 return (INT_MAX - (-match));
00128 else
00129 return (INT_MAX / 2);
00130 }
00131
00132 int
00133 ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg) {
00134 const dns_aclelement_t *matchelt = (const dns_aclelement_t *) arg;
00135 if (dns_aclelement_match(addr, NULL, matchelt,
00136 &ns_g_server->aclenv,
00137 NULL)) {
00138 return (0);
00139 } else {
00140 return (INT_MAX);
00141 }
00142 }
00143
00144 void
00145 ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr,
00146 dns_addressorderfunc_t *orderp,
00147 const void **argp)
00148 {
00149 ns_sortlisttype_t sortlisttype;
00150
00151 sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp);
00152
00153 switch (sortlisttype) {
00154 case NS_SORTLISTTYPE_1ELEMENT:
00155 *orderp = ns_sortlist_addrorder1;
00156 break;
00157 case NS_SORTLISTTYPE_2ELEMENT:
00158 *orderp = ns_sortlist_addrorder2;
00159 break;
00160 case NS_SORTLISTTYPE_NONE:
00161 *orderp = NULL;
00162 break;
00163 default:
00164 UNEXPECTED_ERROR(__FILE__, __LINE__,
00165 "unexpected return from ns_sortlist_setup(): "
00166 "%d", sortlisttype);
00167 break;
00168 }
00169 }
00170