Commit 0deebaea authored by Chen Wei's avatar Chen Wei

change namespace from dict_ to htree_

parent f4ef873e
......@@ -24,7 +24,7 @@ MANDIR = $(PREFIX)/share/man
LOCALEDIR = $(PREFIX)/share/locale
BUILDDIR = $(SRC)
DESTDIR =
CFLAGS = -Wall -W -O2 -g
CFLAGS = -Wall -W -O0 -g
LDFLAGS =
COPTS =
RPM_OPT_FLAGS =
......@@ -73,7 +73,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o dict.o
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o htree.o
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h
......
......@@ -250,7 +250,7 @@ int main (int argc, char **argv)
#endif
#ifdef HAVE_IPSET
if (daemon->dh_ipsets)
if (daemon->htree_ipsets)
ipset_init();
#endif
......
......@@ -510,28 +510,20 @@ struct server {
struct server *next;
};
struct ipsets {
char **sets;
char *domain;
struct ipsets *next;
};
/* a dictionary node for open addressing hash table
* it has a key, "label", and a value "obj" as container, there are several
* other values for maintaining the hash table and lookup
*
* For ipsets match, only INSERT and LOOKUP operation needed
*/
struct dict_node {
char *label; /* key */
void *obj; /* the value, can point to anything */
uint32_t h1; /* from hash function 1 */
uint32_t h2; /* from hash function 2 */
unsigned sub_slots; /* size of hash table sub */
int sub_count; /* items stored in sub */
int sub_loadmax; /* max items stored before upsize sub */
int sub_maxjump; /* max jumps for insertion, upsize when reach */
struct dict_node **sub;
struct htree_node {
char *label; /* key */
void *ptr;
uint32_t h1; /* from hash function 1 */
/*
* hash value from hash function 2, used for double hashing in open
* addressing hash table
*/
uint32_t h2;
struct htree_node **sub; /* the hash table */
unsigned sub_size; /* size of hash table */
int sub_count; /* items stored in hash table */
int sub_loadmax; /* max items stored before upsizing sub */
int sub_maxprobe; /* max probes for insertion, upsizing upon reach */
};
struct special_domain {
......@@ -540,7 +532,6 @@ struct special_domain {
int domain_flags;
};
struct ipsets_names {
char **sets; /* ipsets names end with NULL ptr */
int count;
......@@ -974,11 +965,12 @@ extern struct daemon {
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
struct bogus_addr *bogus_addr, *ignore_addr;
struct server *servers;
struct ipsets *ipsets;
struct dict_node *dh_ipsets;
struct dict_node *dh_ipset_names;
struct dict_node *dh_special_domains;
struct htree_node *htree_ipsets; /* for --ipset domain names*/
/* setnames stored here to reduce redundancy */
struct htree_node *htree_ipset_names;
/* for --server/local/address/rebind-domain-ok domain names */
struct htree_node *htree_special_domains;
int log_fac; /* log facility */
char *log_file; /* optional log file */
......@@ -1405,16 +1397,15 @@ void ipset_init(void);
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove);
#endif
/* dict.c */
/* htree.c */
#define MAXLABELS 128
struct dict_node *new_dictnode (char *label, int len);
struct dict_node *add_or_lookup_dictnode (struct dict_node *node, char *label);
struct dict_node *lookup_domain(struct dict_node *root, char *domain);
struct dict_node *match_domain(struct dict_node *root, char *domain);
struct dict_node *add_or_lookup_domain (struct dict_node *root, char *domain);
struct htree_node *htree_new_node(char *label, int len);
struct htree_node *htree_find_or_add(struct htree_node *node, char *label);
struct htree_node *domain_match(struct htree_node *root, char *domain);
struct htree_node *domain_find_or_add(struct htree_node *root, char *domain);
struct server *lookup_or_install_new_server(struct server *serv);
void free_dicttree (struct dict_node *node);
void print_server_special_domains(struct dict_node *node,
void htree_free (struct htree_node *node);
void print_server_special_domains(struct htree_node *node,
char *parents[], int current_level);
/* helper.c */
......
......@@ -130,9 +130,9 @@ int send_from(int fd, int nowild, char *packet, size_t len,
stored in fwdserv, unless --server=/example.org/#, in which case fwdserv
will be NULL, means use normal server
if matches --rebind-domain-ok, the pass in norebind will be set to 1
if matches --rebind-domain-ok, the passed in norebind will be set to 1
we find largest match, e.g. given pattern debian.org and cn.debian.org,
we find longest match, e.g. given pattern debian.org and cn.debian.org,
ftp.cn.debian.org will match cn.debian.org
*/
static unsigned int
......@@ -143,27 +143,27 @@ search_servers (time_t now, struct all_addr **addrpp,
unsigned int namelen = strlen (qdomain);
unsigned int flags = 0;
unsigned int sflag;
struct dict_node *np;
struct htree_node *np;
struct special_domain *obj;
*type = 0;
/* label of root node is "#", means --address=/#/1.2.3.4 */
if (daemon->dh_special_domains && daemon->dh_special_domains->label &&
*daemon->dh_special_domains->label == '#')
np = daemon->dh_special_domains;
if (daemon->htree_special_domains && daemon->htree_special_domains->label &&
*daemon->htree_special_domains->label == '#')
np = daemon->htree_special_domains;
else
np = match_domain (daemon->dh_special_domains, qdomain);
np = domain_match (daemon->htree_special_domains, qdomain);
if (np != NULL)
{
obj = (struct special_domain *) np->obj;
obj = (struct special_domain *) np->ptr;
*type |= SERV_HAS_DOMAIN;
if (obj->domain_flags & SERV_NO_REBIND)
*norebind = 1;
// no server, domain is local only
/* no server, domain is local only */
if (obj->domain_flags & SERV_NO_ADDR)
{
flags = F_NXDOMAIN;
......@@ -171,7 +171,7 @@ search_servers (time_t now, struct all_addr **addrpp,
}
else if (obj->domain_flags & SERV_LITERAL_ADDRESS)
{
// --address and AF matches
/* --address and AF matches */
sflag = obj->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
if (sflag & qtype)
{
......@@ -187,8 +187,8 @@ search_servers (time_t now, struct all_addr **addrpp,
}
else if (obj->domain_flags & SERV_USE_RESOLV)
{
// --server=8.8.8.8
*type = 0; // use normal server
/* --server=8.8.8.8 */
*type = 0; /* use normal server */
*fwdserv = NULL;
}
......@@ -200,7 +200,7 @@ search_servers (time_t now, struct all_addr **addrpp,
}
else
{
*type = 0; /* use normal servers for this domain */
*type = 0; /* use normal servers for this domain */
*fwdserv = NULL;
}
......@@ -414,7 +414,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
}
#endif
// we have the server for our domain by lookup daemon->dh_special_domains
/* we have the server for our domain by lookup
* daemon->htree_special_domains */
int fd;
/* didn't find a server matches query domain */
......@@ -464,7 +465,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
#endif
}
//TODO how to retry here?
//TODO are we retry correctly here?
if (sendto (fd, (char *) header, plen, 0,
&fwdserv->addr.sa, sa_len (&fwdserv->addr)) == -1)
{
......@@ -519,19 +520,19 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
char **sets = 0;
int munged = 0, is_sign;
size_t plen;
struct dict_node *np;
struct htree_node *np;
struct ipsets_names *obj;
(void)ad_reqd;
(void) do_bit;
#ifdef HAVE_IPSET
if (daemon->dh_ipsets && extract_request(header, n, daemon->namebuff, NULL))
if (daemon->htree_ipsets && extract_request(header, n, daemon->namebuff, NULL))
{
np = match_domain(daemon->dh_ipsets, daemon->namebuff);
np = domain_match(daemon->htree_ipsets, daemon->namebuff);
if (np != NULL)
{
obj = (struct ipsets_names *) np->obj;
obj = (struct ipsets_names *) np->ptr;
sets = obj->sets;
}
}
......
This diff is collapsed.
......@@ -1423,7 +1423,7 @@ void check_servers(void)
enumerate_interfaces(0);
char *levels[MAXLABELS + 1]; /* the root node starts at 1 */
struct dict_node *root = daemon->dh_special_domains;
struct htree_node *root = daemon->htree_special_domains;
print_server_special_domains(root, levels, 0);
for (serv = daemon->servers; serv; serv = serv->next)
......
......@@ -2228,7 +2228,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
char *start_addr, *s;
char *err;
struct server newserv;
struct dict_node *np = NULL;
struct htree_node *np = NULL;
struct special_domain *obj;
memset (&newserv, 0, sizeof (struct server));
......@@ -2238,23 +2238,20 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (arg == NULL)
break;
if (daemon->dh_special_domains == NULL)
daemon->dh_special_domains = new_dictnode (NULL, 0);
if (daemon->htree_special_domains == NULL)
daemon->htree_special_domains = htree_new_node (NULL, 0);
// scan the address part first
// --xxxx=/example.org/ample.com/temple.net/address-of-server
// ^
/* scan the address part first
* --xxxx=/example.org/ample.com/temple.net/address-of-server
* ^ */
start_addr = NULL;
if (strchr (arg, '/') == NULL)
{
// --xxxx=example.org (only availabe for --rebind-domain-ok)
/* --xxxx=example.org (only availabe for --rebind-domain-ok) */
if (option == LOPT_NO_REBIND)
newserv.flags |= SERV_NO_REBIND;
else if (option == 'S')
{
// --server=8.8.8.8
start_addr = arg;
}
start_addr = arg; /* --server=8.8.8.8 */
}
else
......@@ -2273,10 +2270,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (*start_addr == '#')
{
newserv.flags |= SERV_USE_RESOLV;
}
else if (*start_addr == '\0')
/* --xxxx=/example.org/here-is-empty */
else if (*start_addr == '\0')
{
/* give --server domain but no ip means the domain is local and
* it may answer queries from /etc/hosts or DHCP but should
......@@ -2287,10 +2284,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (option == 'A')
ret_err ("--address must specify address");
}
/* --xxxx=/example.org/8.8.8.8#53@source-ip|interface#port
* --xxxx=8.8.8.8 */
else
{
/* --xxxx=/example.org/8.8.8.8#53@source-ip|interface#port
* --xxxx=8.8.8.8 */
err =
parse_server (start_addr, &newserv.addr, &newserv.source_addr,
newserv.interface, &newserv.flags);
......@@ -2300,21 +2298,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
// --server
/* --server */
if (servers_only && option == 'S')
newserv.flags |= SERV_FROM_FILE;
// --rebind-domain-ok
/* --rebind-domain-ok */
if (option == LOPT_NO_REBIND)
newserv.flags |= SERV_NO_REBIND;
// --address will be handled inside the domain dict_node
/* --address will be handled inside the domain htree_node */
// the arg pattern can be
// --xxxx=example.org (only availabe for --rebind-domain-ok) or
// --xxxx=/example.org/ or
// --xxxx=/example.org/ample.com/temple.net/
/* the arg pattern can be
* --xxxx=example.org (only availabe for --rebind-domain-ok) or
* --xxxx=/example.org/ or
* --xxxx=/example.org/ample.com/temple.net/ */
if (*arg == '/' || option == LOPT_NO_REBIND)
{
int rebind = !(*arg == '/');
......@@ -2328,15 +2326,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
while (*arg == '.')
arg++;
// wrong config option --xxxx=/./1.2.3.4
/* wrong config option --xxxx=/./1.2.3.4 */
if (strlen (arg) == 0)
continue;
// --address=/#/1.2.3.4
// use label in the root node to mark #(match all domains)
/* --address=/#/1.2.3.4
* use label in the root node to mark #(match all domains) */
if (strcmp (arg, "#") == 0)
{
np = daemon->dh_special_domains;
np = daemon->htree_special_domains;
free(np->label);
np->label = strdup("#");
}
......@@ -2346,15 +2344,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
else
{
np = add_or_lookup_domain(daemon->dh_special_domains, domain);
np = domain_find_or_add(daemon->htree_special_domains, domain);
}
free(domain);
// domain unrecognizable
/* domain unrecognizable */
if (np == NULL)
continue;
if (np->obj == NULL)
if (np->ptr == NULL)
{
obj = opt_malloc (sizeof (struct special_domain));
memset (obj, 0, sizeof (struct special_domain));
......@@ -2362,7 +2360,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
else
{
obj = (struct special_domain *) np->obj;
obj = (struct special_domain *) np->ptr;
}
obj->domain_flags = newserv.flags;
......@@ -2383,7 +2381,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
/* pointer to one of servers in daemon->servers link
* list, no memory will be leaked if obj->server been
* overwritten*/
* overwritten */
newserv.flags |= SERV_HAS_DOMAIN;
obj->server = lookup_or_install_new_server (&newserv);
obj->server->domain = NULL;
......@@ -2393,8 +2391,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (option == LOPT_NO_REBIND)
{
// the rebind flag here instead of the one in struct server
// will be used by forward
/* the rebind flag here instead of the one in struct server
* will be used by forward */
obj->domain_flags |= SERV_NO_REBIND;
}
......@@ -2403,15 +2401,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
obj->domain_flags |= SERV_NO_ADDR;
}
//newserv.flags |= domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
np->obj = (void *) obj;
np->ptr = (void *) obj;
arg = end;
if (rebind)
break;
}
}
// --server=8.8.8.8
/* --server=8.8.8.8 */
else if ((strchr (arg, '/') == NULL && option == 'S'))
{
lookup_or_install_new_server (&newserv);
......@@ -2465,16 +2462,16 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
char **sets, **sets_pos;
int sets_count = 0;
unhide_metas (arg);
struct dict_node *np = NULL;
struct dict_node *setname = NULL;
struct htree_node *np = NULL;
struct htree_node *setname = NULL;
struct ipsets_names *obj;
char *domain = NULL;
if (daemon->dh_ipsets == NULL)
daemon->dh_ipsets = new_dictnode (NULL, 0);
if (daemon->htree_ipsets == NULL)
daemon->htree_ipsets = htree_new_node (NULL, 0);
if (daemon->dh_ipset_names == NULL)
daemon->dh_ipset_names = new_dictnode (NULL, 0);
if (daemon->htree_ipset_names == NULL)
daemon->htree_ipset_names = htree_new_node (NULL, 0);
if (arg && *arg == '/')
{
......@@ -2493,7 +2490,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
option = '?';
if (domain != NULL)
np = add_or_lookup_domain (daemon->dh_ipsets, domain);
np = domain_find_or_add (daemon->htree_ipsets, domain);
free(domain);
arg = end;
......@@ -2515,8 +2512,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
do
{
end = split (arg);
// only store one copy of setname in daemon->dh_ipset_names
setname = add_or_lookup_dictnode(daemon->dh_ipset_names, arg);
// only store one copy of setname in daemon->htree_ipset_names
setname = htree_find_or_add(daemon->htree_ipset_names, arg);
*sets_pos++ = setname->label;
sets_count++;
arg = end;
......@@ -2530,12 +2527,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
obj = opt_malloc(sizeof(struct ipsets_names));
obj->sets = sets;
obj->count = sets_count;
if (np->obj != NULL) {
old_obj = (struct ipsets_names *) np->obj;
if (np->ptr != NULL) {
old_obj = (struct ipsets_names *) np->ptr;
free(old_obj->sets);
free(old_obj);
}
np->obj = (void *) obj;
np->ptr = (void *) obj;
}
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment