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;
}
}
......
/* dict.c is Copyright (c) 2015 Chen Wei <weichen302@gmail.com>
/* htree.c Chen Wei <weichen302@gmail.com>
Use cascade of open addressing hash tables to store config options that
involve domain names.
......@@ -26,9 +26,6 @@
values are compared first, only if they are match, should the more
expensive string comparison be used to confirm the search.
The search should take constant time regardless the size of --ipset and
--server rules.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -46,17 +43,17 @@
#include "dnsmasq.h"
#define OPEN_ADDRESSING_MAXJUMP 7 /* no reason, just like 7 */
#define OPEN_ADDRESSING_DEFAULT_SLOT 4
#define OPEN_ADDRESSING_MAXPROBE 7
#define OPEN_ADDRESSING_DEFAULT_SIZE 4
#define FNV1_32A_INIT ((uint32_t)0x811c9dc5)
#define max(A, B) ((A) > (B) ? (A) : (B))
static char buf[MAXDNAME];
/* prototypes */
static struct dict_node *lookup_dictnode (struct dict_node *node, char *label);
static void add_dicttree (struct dict_node *node, struct dict_node *sub);
static void upsize_dicttree (struct dict_node *np);
static struct htree_node *htree_find (struct htree_node *node, char *label);
static void htree_add (struct htree_node *node, struct htree_node *sub);
static void htree_upsizing (struct htree_node *np);
static inline void normalize_domain_name (char *dst, char *src, int len);
/* hash function 1 for double hashing
......@@ -90,7 +87,7 @@ static inline uint32_t dblhash_2 (char *key)
}
/* convert domain to lower cases, remove leading blank, leading and trailing
* dot, string end with \0 */
* dot. End string with \0 */
static inline void normalize_domain_name (char *d, char *s, int len)
{
int i;
......@@ -122,28 +119,28 @@ static inline void normalize_domain_name (char *d, char *s, int len)
d[i] = '\0';
}
struct dict_node * init_sub_dictnode (struct dict_node *node)
struct htree_node * htree_init_sub (struct htree_node *node)
{
unsigned n;
if (node->sub != NULL)
return node;
node->sub_slots = OPEN_ADDRESSING_DEFAULT_SLOT;
node->sub_loadmax = node->sub_slots * 3 / 4; // loading factor 0.75
node->sub = safe_malloc (node->sub_slots * sizeof (struct dict_node *));
for (n = 0; n < node->sub_slots; n++)
node->sub_size = OPEN_ADDRESSING_DEFAULT_SIZE;
node->sub_loadmax = node->sub_size * 3 / 4; /* max loading factor 0.75 */
node->sub = safe_malloc (node->sub_size * sizeof (struct htree_node *));
for (n = 0; n < node->sub_size; n++)
node->sub[n] = NULL;
return node;
}
/* allocate and initialize a new node */
struct dict_node * new_dictnode (char *label, int label_len)
struct htree_node * htree_new_node (char *label, int label_len)
{
struct dict_node *node;
struct htree_node *node;
node = safe_malloc (sizeof (struct dict_node));
node = safe_malloc (sizeof (struct htree_node));
if (node == NULL)
return NULL;
......@@ -161,59 +158,59 @@ struct dict_node * new_dictnode (char *label, int label_len)
}
node->sub_count = 0;
node->sub_slots = 0;
node->sub_size = 0;
node->sub_loadmax = 0;
node->sub_maxjump = 0;
node->sub_maxprobe = 0;
node->sub = NULL;
node->obj = NULL;
node->ptr = NULL;
return node;
}
/* double the slots of dns node, it calls with add_dicttree each other
* the table size starts with 2^2, so that the new size remains 2^x, the
* double hash used is choosed to work with 2^n slots and perform well */
static void upsize_dicttree (struct dict_node *np)
/* double the size of hash table attached to a htree_node, it calls with
* htree_add with each other. The table size starts with 2^2, so that the new
* size remains 2^x, the double hash used is chosen to work with 2^n slots */
static void htree_upsizing (struct htree_node *np)
{
struct dict_node **oldnodes;
struct htree_node **oldnodes;
unsigned i, oldsize;
oldsize = np->sub_slots;
oldsize = np->sub_size;
oldnodes = np->sub;
np->sub_slots = oldsize * 2;
np->sub_loadmax = np->sub_slots * 3 / 4;
np->sub_size = oldsize * 2;
np->sub_loadmax = np->sub_size * 3 / 4;
np->sub_count = 0;
np->sub_maxjump = 0;
np->sub = safe_malloc (np->sub_slots * sizeof (struct dict_node *));
for (i = 0; i < np->sub_slots; i++)
np->sub_maxprobe = 0;
np->sub = safe_malloc (np->sub_size * sizeof (struct htree_node *));
for (i = 0; i < np->sub_size; i++)
np->sub[i] = NULL;
for (i = 0; i < oldsize; i++)
{
if (oldnodes[i] != NULL)
{
add_dicttree (np, oldnodes[i]);
htree_add (np, oldnodes[i]);
}
}
free (oldnodes);
}
/* add a sub-node, upsize if needed, calls with upsize_dicttree each other */
static void add_dicttree (struct dict_node *node, struct dict_node *sub)
/* add a sub-node, upsize if needed, calls with htree_upsizing with each other */
static void htree_add (struct htree_node *node, struct htree_node *sub)
{
int n;
uint32_t dh, idx;
if (node->sub == NULL)
init_sub_dictnode (node);
htree_init_sub (node);
n = 0;
dh = sub->h1;
while (1)
{
/* eq to dh % node->sub_slots, since sub_slots is power of 2*/
idx = dh & (node->sub_slots - 1);
/* eq to dh % node->sub_size, since sub_size is power of 2*/
idx = dh & (node->sub_size - 1);
if (node->sub[idx] == NULL)
{
node->sub[idx] = sub;
......@@ -227,63 +224,56 @@ static void add_dicttree (struct dict_node *node, struct dict_node *sub)
}
}
node->sub_maxjump = max (n, node->sub_maxjump);
/* If it takes a lots of jumps to find an empty slot, or the used slots
* close to loading max, upsize the table */
if (node->sub_maxjump > OPEN_ADDRESSING_MAXJUMP ||
node->sub_maxprobe = max (n, node->sub_maxprobe);
/*
* If it takes a lots of probes to find an empty slot, or the used slots
* close to loading max, upsize the table
*/
if (node->sub_maxprobe > OPEN_ADDRESSING_MAXPROBE ||
node->sub_count > node->sub_loadmax)
{
upsize_dicttree (node);
htree_upsizing (node);
}
return;
}
/* add a new subnode to node, or update the attr of the subnode with same
* label
* return the subnode */
struct dict_node *add_or_lookup_dictnode (struct dict_node *node, char *label)
struct htree_node *htree_find_or_add (struct htree_node *node, char *label)
{
struct dict_node *np;
struct htree_node *np;
if ((np = lookup_dictnode (node, label)) == NULL)
if ((np = htree_find (node, label)) == NULL)
{
if (node->sub == NULL)
{
init_sub_dictnode (node);
}
np = new_dictnode (label, strlen (label));
add_dicttree (node, np);
htree_init_sub (node);
np = htree_new_node (label, strlen (label));
htree_add (node, np);
}
return np;
}
/* lookup the label in node's sub, return pointer if found, NULL if not */
static struct dict_node *lookup_dictnode (struct dict_node *node, char *label)
/* lookup the label in node's sub, return the pointer, NULL if not found */
static struct htree_node *htree_find (struct htree_node *node, char *label)
{
uint32_t h1, h2, dh, idx;
struct dict_node *np;
struct htree_node *np;
/* this domain doesn't have sub-domains */
if (node->sub == NULL)
{
return NULL;
}
return NULL;
dh = h1 = dblhash_1 (label);
h2 = dblhash_2 (label);
idx = dh & (node->sub_slots - 1);
idx = dh & (node->sub_size - 1);
while ((np = node->sub[idx]) != NULL)
{
if (np->h1 == h1 && np->h2 == h2)
if (strcmp (np->label, label) == 0)
{
return np;
}
return np;
dh += h2;
idx = dh & (node->sub_slots - 1);
idx = dh & (node->sub_size - 1);
}
return NULL;
......@@ -291,16 +281,16 @@ static struct dict_node *lookup_dictnode (struct dict_node *node, char *label)
/* look up the whole domain pattern by step over DNS name hierarchy top down.
* for example, if the pattern is cn.debian.org, the lookup will start with
* org, then debian, then cn */
struct dict_node * match_domain(struct dict_node *root, char *domain)
* org, then debian, then cn. The longest pattern wins. */
struct htree_node * domain_match(struct htree_node *root, char *domain)
{
char *labels[MAXLABELS];
int i, label_num;
int len = (int) sizeof(buf);
struct dict_node *node, *res;
struct htree_node *node, *res;
if (root == NULL)
return NULL;
return NULL;
memset(buf, 0, sizeof(buf));
normalize_domain_name (buf, domain, len);
......@@ -325,69 +315,27 @@ struct dict_node * match_domain(struct dict_node *root, char *domain)
res = NULL;
for (i = label_num - 1; i >= 0; i--)
{
node = lookup_dictnode (node, labels[i]);
/* match longest pattern, e.g. for pattern debian.org and cn.debian.org,
* domain name ftp.cn.debian.org will match pattern cn.debian.org */
node = htree_find (node, labels[i]);
if (node == NULL)
break;
break;
if (node->obj != NULL)
res = node;
/* repeatedly overwrite with node that has option set while walk down the
* domain name tree to match config option with longest pattern */
if (node->ptr != NULL)
res = node;
}
if (res == NULL)
return NULL;
return res;
}
/* look up the whole domain pattern by step over DNS name hierarchy top down.
* for example, if the pattern is cn.debian.org, the lookup will start with
* org, then debian, then cn */
struct dict_node * lookup_domain (struct dict_node *root, char *domain)
{
char *labels[MAXLABELS];
int i, label_num;
int len = (int) sizeof(buf);
struct dict_node *node;
memset(buf, 0, sizeof(buf));
normalize_domain_name (buf, domain, len);
for (i = 0; i < MAXLABELS; i++)
labels[i] = NULL;
label_num = 0;
labels[label_num++] = &buf[0];
for (i = 0; i < len && buf[i] != '\0'; i++)
{
if (buf[i] == '.')
{
buf[i] = '\0';
labels[label_num++] = &buf[i + 1];
}
}
node = root;
for (i = label_num - 1; i >= 0 && node != NULL; i--)
{
node = lookup_dictnode (node, labels[i]);
}
return i == -1 ? node : NULL;
}
/* add a domain pattern in the form of debian.org to root
* return the node with lowest hierarchy */
struct dict_node *add_or_lookup_domain (struct dict_node *root, char *domain)
/* add a domain pattern in the form of debian.org to root or find the node
* match the domain pattern (for modify) */
struct htree_node *domain_find_or_add (struct htree_node *root, char *domain)
{
char *labels[MAXLABELS];
int i, label_num;
int len = (int) sizeof(buf);
struct dict_node *node;
struct htree_node *node;
memset(buf, 0, sizeof(buf));
normalize_domain_name (buf, domain, len);
......@@ -409,22 +357,20 @@ struct dict_node *add_or_lookup_domain (struct dict_node *root, char *domain)
node = root;
for (i = label_num - 1; i >= 0; i--)
{
node = add_or_lookup_dictnode (node, labels[i]);
}
node = htree_find_or_add (node, labels[i]);
return node;
}
/* free node and all sub-nodes recursively. Unused. */
void free_dicttree (struct dict_node *node)
void htree_free (struct htree_node *node)
{
struct dict_node *np;
struct htree_node *np;
unsigned i;
if (node->sub_count > 0)
{
for (i = 0; i < node->sub_slots; i++)
for (i = 0; i < node->sub_size; i++)
{
np = node->sub[i];
if (np != NULL)
......@@ -432,10 +378,10 @@ void free_dicttree (struct dict_node *node)
if (np->label != NULL)
free (np->label);
if (np->obj != NULL)
free (np->obj);
if (np->ptr != NULL)
free (np->ptr);
free_dicttree (np);
htree_free (np);
}
}
free (node->sub);
......@@ -476,7 +422,7 @@ static inline struct server *serverdup(struct server *src)
* servers in daemon->servers link list. If no match found, then insert a new
* server
*
* Return the lookup result or the newly created server*/
* Return the lookup result or the newly created server */
struct server *lookup_or_install_new_server(struct server *serv)
{
struct server *res;
......@@ -496,13 +442,11 @@ struct server *lookup_or_install_new_server(struct server *serv)
return res;
}
/* print the daemon->dh_special_domains tree recursively
*
* do we really need it? */
void print_server_special_domains (struct dict_node *node,
/* print the daemon->htree_special_domains tree recursively */
void print_server_special_domains (struct htree_node *node,
char *parents[], int current_level)
{
struct dict_node *np;
struct htree_node *np;
struct special_domain *obj;
char buf[MAXDNAME];
char ip_buf[16];
......@@ -514,9 +458,9 @@ void print_server_special_domains (struct dict_node *node,
if (node->label != NULL)
{
parents[level] = node->label;
if (node->obj != NULL)
if (node->ptr != NULL)
{
obj = (struct special_domain *) node->obj;
obj = (struct special_domain *) node->ptr;
if (obj->domain_flags & SERV_HAS_DOMAIN)
{
memset (buf, 0, MAXDNAME);
......@@ -535,7 +479,7 @@ void print_server_special_domains (struct dict_node *node,
if (node->sub_count > 0)
{
for (i = 0; i < node->sub_slots; i++)
for (i = 0; i < node->sub_size; i++)
if ((np = node->sub[i]) != NULL)
print_server_special_domains (np, parents, level);
}
......
......@@ -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