[sr-dev] git:master: dns cache: fix manually inserted SRV record order

Miklos Tirpak miklos at iptel.org
Wed Aug 18 15:44:45 CEST 2010


Module: sip-router
Branch: master
Commit: 78beed37b8975e11851553c41c17578481772dad
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=78beed37b8975e11851553c41c17578481772dad

Author: Miklos Tirpak <miklos at iptel.org>
Committer: Miklos Tirpak <miklos at 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;
+				}
+			}
 		}
 	}
 




More information about the sr-dev mailing list