diff --git a/src/cache.c b/src/cache.c index 5b91854..b4dcd0e 100644 --- a/src/cache.c +++ b/src/cache.c @@ -77,17 +77,20 @@ static void cache_link(struct crec *crecp); static void rehash(int size); static void cache_hash(struct crec *crecp); -static unsigned int next_uid(void) +void next_uid(struct crec *crecp) { static unsigned int uid = 0; - uid++; + if (crecp->uid == UID_NONE) + { + uid++; - /* uid == 0 used to indicate CNAME to interface name. */ - if (uid == SRC_INTERFACE) - uid++; - - return uid; + /* uid == 0 used to indicate CNAME to interface name. */ + if (uid == UID_NONE) + uid++; + + crecp->uid = uid; + } } void cache_init(void) @@ -105,7 +108,7 @@ void cache_init(void) { cache_link(crecp); crecp->flags = 0; - crecp->uid = next_uid(); + crecp->uid = UID_NONE; } } @@ -204,7 +207,7 @@ static void cache_free(struct crec *crecp) { crecp->flags &= ~F_FORWARD; crecp->flags &= ~F_REVERSE; - crecp->uid = next_uid(); /* invalidate CNAMES pointing to this. */ + crecp->uid = UID_NONE; /* invalidate CNAMES pointing to this. */ if (cache_tail) cache_tail->next = crecp; @@ -787,8 +790,9 @@ static void add_hosts_cname(struct crec *target) crec->ttd = a->ttl; crec->name.namep = a->alias; crec->addr.cname.target.cache = target; + next_uid(target); crec->addr.cname.uid = target->uid; - crec->uid = next_uid(); + crec->uid = UID_NONE; cache_hash(crec); add_hosts_cname(crec); /* handle chains */ } @@ -1071,7 +1075,7 @@ void cache_reload(void) cache->name.namep = a->alias; cache->addr.cname.target.int_name = intr; cache->addr.cname.uid = SRC_INTERFACE; - cache->uid = next_uid(); + cache->uid = UID_NONE; cache_hash(cache); add_hosts_cname(cache); /* handle chains */ } @@ -1201,8 +1205,9 @@ static void add_dhcp_cname(struct crec *target, time_t ttd) aliasc->ttd = ttd; aliasc->name.namep = a->alias; aliasc->addr.cname.target.cache = target; + next_uid(target); aliasc->addr.cname.uid = target->uid; - aliasc->uid = next_uid(); + aliasc->uid = UID_NONE; cache_hash(aliasc); add_dhcp_cname(aliasc, ttd); } @@ -1290,7 +1295,7 @@ void cache_add_dhcp_entry(char *host_name, int prot, crec->ttd = ttd; crec->addr.addr = *host_address; crec->name.namep = host_name; - crec->uid = next_uid(); + crec->uid = UID_NONE; cache_hash(crec); add_dhcp_cname(crec, ttd); diff --git a/src/dnsmasq.h b/src/dnsmasq.h index e31889b..a7c3ea8 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -468,8 +468,12 @@ struct crec { #define F_SERVFAIL (1u<<28) #define F_RCODE (1u<<29) +#define UID_NONE 0 /* Values of uid in crecs with F_CONFIG bit set. */ -#define SRC_INTERFACE 0 +/* cname to uid SRC_INTERFACE are to interface names, + so use UID_NONE for that to eliminate clashes with + any other uid */ +#define SRC_INTERFACE UID_NONE #define SRC_CONFIG 1 #define SRC_HOSTS 2 #define SRC_AH 3 @@ -1117,6 +1121,7 @@ extern struct daemon { /* cache.c */ void cache_init(void); +void next_uid(struct crec *crecp); void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg); char *record_source(unsigned int index); char *querystr(char *desc, unsigned short type); diff --git a/src/rfc1035.c b/src/rfc1035.c index 580f5ef..e179865 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -788,6 +788,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t newc->addr.cname.uid = 1; if (cpp) { + next_uid(newc); cpp->addr.cname.target.cache = newc; cpp->addr.cname.uid = newc->uid; } @@ -844,6 +845,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag); if (newc && cpp) { + next_uid(newc); cpp->addr.cname.target.cache = newc; cpp->addr.cname.uid = newc->uid; } @@ -870,6 +872,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0)); if (newc && cpp) { + next_uid(newc); cpp->addr.cname.target.cache = newc; cpp->addr.cname.uid = newc->uid; }