Module: sip-router
Branch: master
Commit: 78beed37b8975e11851553c41c17578481772dad
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=78beed3…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Wed Aug 18 15:32:36 2010 +0200
dns cache: fix manually inserted SRV record order
The manually inserted SRV records thought the RPC interface
were not ordered by their priority and weight which resulted in
wrong SRV look-ups, i.e. not the highest priority record
was chosen first.
---
dns_cache.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/dns_cache.c b/dns_cache.c
index 182e61f..ef3a986 100644
--- a/dns_cache.c
+++ b/dns_cache.c
@@ -4221,6 +4221,8 @@ int dns_cache_add_record(unsigned short type,
ticks_t expire;
int err, h;
int size;
+ struct dns_rr *new_rr, **rr_p, **rr_iter;
+ struct srv_rdata *srv_rd;
/* eliminate gcc warnings */
ip_addr = 0;
@@ -4358,6 +4360,7 @@ int dns_cache_add_record(unsigned short type,
/* let the rr point to the new structure */
rr = (struct dns_rr*)translate_pointer((char*)new, (char*)old,
(char*)rr);
+ new_rr = rr;
if (type == T_SRV) {
/* fix the priority, weight, and port */
@@ -4392,6 +4395,7 @@ int dns_cache_add_record(unsigned short type,
"DNS cache entry\n");
goto error;
}
+ new_rr = rr;
switch(type) {
case T_A:
@@ -4409,6 +4413,46 @@ int dns_cache_add_record(unsigned short type,
/* maximum expire value has been already fixed by
* dns_cache_clone_entry() */
}
+
+ if (type == T_SRV) {
+ /* SRV records must be ordered by their priority and weight.
+ * With modifying an exising rr, or adding new rr to the DNS entry,
+ * the ordered list might got broken which needs to be fixed.
+ */
+ rr_p = NULL;
+ for ( rr_iter = &new->rr_lst;
+ *rr_iter;
+ rr_iter = &((*rr_iter)->next)
+ ) {
+ if (*rr_iter == new_rr) {
+ rr_p = rr_iter;
+ continue;
+ }
+ srv_rd = (struct srv_rdata*)(*rr_iter)->rdata;
+ if ((priority < srv_rd->priority) ||
+ ((priority == srv_rd->priority) && (weight > srv_rd->weight))
+ )
+ break; /* insert here */
+ }
+
+ if (!rr_p)
+ for ( rr_p = rr_iter;
+ *rr_p && (*rr_p != new_rr);
+ rr_p = &((*rr_p)->next)
+ );
+ if (!rr_p) {
+ LOG(L_ERR, "ERROR: Failed to correct the orderd list of SRV resource
records\n");
+ goto error;
+ }
+
+ if (*rr_iter != new_rr->next) {
+ /* unlink rr from the list */
+ *rr_p = (*rr_p)->next;
+ /* link it before *rr_iter */
+ new_rr->next = *rr_iter;
+ *rr_iter = new_rr;
+ }
+ }
}
}