Bugfix: when matching RR entries, sometimes the name and type are not sufficiently unique.

- Added rr_entry_match() to search for an exact RR entry. For most RRs,
  matching its name is sufficient but for PTRs, its target needs to be
  matched as well.

- Rewrote populate_answers() logic to make sure all matching RRs (by
  name and type) are added.

- When responding, populate our answers first, then check them against
  the Known-Answer list.
This commit is contained in:
Darell Tan
2012-10-15 22:47:15 +08:00
parent 4e19b7120e
commit c4993739f5
3 changed files with 64 additions and 29 deletions

22
mdns.c
View File

@@ -47,11 +47,6 @@ struct name_comp {
// ----- label functions -----
// compares 2 names
static inline int cmp_nlabel(const uint8_t *L1, const uint8_t *L2) {
return strcmp((char *) L1, (char *) L2);
}
// duplicates a name
inline uint8_t *dup_nlabel(const uint8_t *n) {
assert(n[0] <= 63); // prevent mis-use
@@ -463,6 +458,23 @@ struct rr_entry *rr_entry_find(struct rr_list *rr_list, uint8_t *name, uint16_t
return NULL;
}
// looks for a matching entry in rr_list
// if entry is a PTR, we need to check if the PTR target also matches
struct rr_entry *rr_entry_match(struct rr_list *rr_list, struct rr_entry *entry) {
struct rr_list *rr = rr_list;
for (; rr; rr = rr->next) {
if (rr->e->type == entry->type && cmp_nlabel(rr->e->name, entry->name) == 0) {
if (entry->type != RR_PTR) {
return rr->e;
} else if (cmp_nlabel(MDNS_RR_GET_PTR_NAME(entry), MDNS_RR_GET_PTR_NAME(rr->e)) == 0) {
// if it's a PTR, we need to make sure PTR target also matches
return rr->e;
}
}
}
return NULL;
}
void rr_group_destroy(struct rr_group *group) {
struct rr_group *g = group;