Module: kamailio
Branch: master
Commit: 28049aafc8dd06c160ce5e7b8d5e4fc728441b0c
URL:
https://github.com/kamailio/kamailio/commit/28049aafc8dd06c160ce5e7b8d5e4fc…
Author: Semen Darienko <semen.darienko(a)wildix.com>
Committer: Daniel-Constantin Mierla <miconda(a)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/28049aafc8dd06c160ce5e7b8d5e4fc…
Patch:
https://github.com/kamailio/kamailio/commit/28049aafc8dd06c160ce5e7b8d5e4fc…
---
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 */
};