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