[sr-dev] git:master:28049aaf: core: dns - use all NAPTR records

Daniel-Constantin Mierla miconda at gmail.com
Sun May 3 12:28:21 CEST 2020


Module: kamailio
Branch: master
Commit: 28049aafc8dd06c160ce5e7b8d5e4fc728441b0c
URL: https://github.com/kamailio/kamailio/commit/28049aafc8dd06c160ce5e7b8d5e4fc728441b0c

Author: Semen Darienko <semen.darienko at wildix.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2020-05-03T12:26:45+02:00

core: dns - use all NAPTR records

- enable using of all NAPTR records instead of the first one ordered by
priority
- GH #2290

---

Modified: src/core/dns_cache.c
Modified: src/core/resolve.c
Modified: src/core/resolve.h

---

Diff:  https://github.com/kamailio/kamailio/commit/28049aafc8dd06c160ce5e7b8d5e4fc728441b0c.diff
Patch: https://github.com/kamailio/kamailio/commit/28049aafc8dd06c160ce5e7b8d5e4fc728441b0c.patch

---

diff --git a/src/core/dns_cache.c b/src/core/dns_cache.c
index 81fc6a9e45..c8567813e5 100644
--- a/src/core/dns_cache.c
+++ b/src/core/dns_cache.c
@@ -2644,6 +2644,10 @@ struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
 		}
 		LM_DBG("found a valid sip NAPTR rr %.*s, proto %d\n",
 				naptr->repl_len, naptr->repl, (int)naptr_proto);
+		if (naptr->skip_record) {
+			i++;
+			continue;
+		}
 		if ((naptr_proto_supported(naptr_proto))){
 			if (naptr_choose(&naptr_saved, &saved_proto,
 								naptr, naptr_proto))
@@ -3203,6 +3207,63 @@ inline static int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
 
 
 #ifdef USE_NAPTR
+
+
+static void mark_skip_current_naptr(struct dns_rr* naptr_head, struct dns_hash_entry* srv)
+{
+	int i;
+	struct dns_rr* l;
+	struct naptr_rdata* naptr;
+
+	if (!naptr_head || !srv) {
+		return;
+	}
+
+	for(l=naptr_head, i=0; l && (i<MAX_NAPTR_RRS); l=l->next, i++) {
+		naptr = (struct naptr_rdata *) l->rdata;
+		if (naptr == 0) {
+			break;
+		}
+		if (naptr->skip_record) {
+			continue;
+		}
+		if (srv->name_len == naptr->repl_len && !memcmp(srv->name, naptr->repl, srv->name_len)) {
+			naptr->skip_record = 1;
+			LM_NOTICE("Mark to skip %.*s NAPTR record due to all IPs are unreachable\n", naptr->repl_len, naptr->repl);
+			break;
+		}
+	}
+}
+
+
+inline static int have_more_active_naptr(struct dns_rr* naptr_head)
+{
+	int i, res = 0;
+	struct dns_rr* l;
+	struct naptr_rdata* naptr;
+	char naptr_proto;
+
+	if (!naptr_head) {
+		return res;
+	}
+
+	for(l=naptr_head, i=0; l && (i<MAX_NAPTR_RRS); l=l->next, i++) {
+		naptr = (struct naptr_rdata *) l->rdata;
+		if (naptr == 0) {
+			break;
+		}
+		if (naptr->skip_record) {
+			continue;
+		} else if ((naptr_proto = naptr_get_sip_proto(naptr)) <= 0) {
+			continue;
+		} else if ((naptr_proto_supported(naptr_proto))) {
+			res = 1;
+			break;
+		}
+	}
+	return res;
+}
+
 /* resolves a host name trying:
  * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
  *    *port==0 and *proto=0 and if flags allow NAPTR lookups
@@ -3227,6 +3288,7 @@ inline static int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
 	char n_proto, origproto;
 	str srv_name;
 	int ret;
+	int try_lookup_naptr = 0;
 
 	ret=-E_DNS_NO_NAPTR;
 	if(proto) origproto=*proto;
@@ -3259,9 +3321,27 @@ inline static int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
 			*port=h->port;
 			return 0;
 		}
-		/* do naptr lookup */
-		if ((e=dns_get_entry(name, T_NAPTR))==0)
-			goto naptr_not_found;
+		try_lookup_naptr = 1;
+	}
+	/* do naptr lookup */
+	if ((e=dns_get_entry(name, T_NAPTR))==0)
+		goto naptr_not_found;
+
+	if (!try_lookup_naptr) {
+		if(proto) *proto=origproto;
+		int res = dns_srv_sip_resolve(h, name, ip, port, proto, flags);
+		if (res) {
+			mark_skip_current_naptr(e->rr_lst, h->srv);
+			if (have_more_active_naptr(e->rr_lst)) {
+				// No more avaliable IP for current NAPTR record, let's try next one
+				try_lookup_naptr = 1;
+			}
+		} else {
+			return res;
+		}
+	}
+
+	if (try_lookup_naptr) {
 		naptr_iterate_init(&tried_bmp);
 		while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
 												&srv_name, &n_proto)){
diff --git a/src/core/resolve.c b/src/core/resolve.c
index af269a2b42..193ac528af 100644
--- a/src/core/resolve.c
+++ b/src/core/resolve.c
@@ -407,6 +407,7 @@ struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
 		PKG_MEM_ERROR;
 		goto error;
 	}
+	naptr->skip_record = 0;
 	naptr->order=ntohs(order);
 	naptr->pref=ntohs(pref);
 	
diff --git a/src/core/resolve.h b/src/core/resolve.h
index 5ef849ccf8..d49ebdc206 100644
--- a/src/core/resolve.h
+++ b/src/core/resolve.h
@@ -123,6 +123,7 @@ struct naptr_rdata {
 	unsigned char services_len;
 	unsigned char regexp_len;
 	unsigned char repl_len; /* not currently used */
+	unsigned char skip_record;
 	
 	char str_table[1]; /* contains all the strings */
 };




More information about the sr-dev mailing list