Module: kamailio
Branch: master
Commit: 34844f3b235235c9d44681f89098893967e3b408
URL: 
https://github.com/kamailio/kamailio/commit/34844f3b235235c9d44681f89098893967e3b408

Author: Kilian Wöber <[email protected]>
Committer: Henning Westerholt <[email protected]>
Date: 2026-03-10T09:10:26+01:00

core: dns - Fix lookup of multiple NAPTR entries

- Allow storing NAPTR entries in dns_srv_handle
- When resolving NAPTR, try to reuse entry after initial lookup

---

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

---

Diff:  
https://github.com/kamailio/kamailio/commit/34844f3b235235c9d44681f89098893967e3b408.diff
Patch: 
https://github.com/kamailio/kamailio/commit/34844f3b235235c9d44681f89098893967e3b408.patch

---

diff --git a/src/core/dns_cache.c b/src/core/dns_cache.c
index b84c628cb3c..e43dac3036a 100644
--- a/src/core/dns_cache.c
+++ b/src/core/dns_cache.c
@@ -3430,7 +3430,7 @@ inline static int dns_naptr_sip_resolve(struct 
dns_srv_handle *h, str *name,
                }
                return -E_DNS_NO_NAPTR;
        }
-       if(((h->srv == 0) && (h->a == 0)) && /* first call */
+       if(((h->srv == 0) && (h->a == 0) && (h->naptr == 0)) && /* first call */
                        proto && port && (*proto == 0) && (*port == 0)) {
                *proto = PROTO_UDP; /* just in case we don't find another */
 
@@ -3447,14 +3447,20 @@ 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;
+               h->naptr = e;
                try_lookup_naptr = 1;
+       } else {
+               /* access old naptr lookup */
+               if((e = h->naptr) == 0)
+                       goto naptr_not_found;
        }
        /* check if it's an ip address, dns_srv_sip_resolve will return the 
right failure */
        if(str2ip(name) || str2ip6(name))
                goto naptr_not_found;
-       /* do naptr lookup */
-       if((e = dns_get_entry(name, T_NAPTR)) == 0)
-               goto naptr_not_found;
 
        if(!try_lookup_naptr) {
                if(proto)
@@ -3475,7 +3481,7 @@ inline static int dns_naptr_sip_resolve(struct 
dns_srv_handle *h, str *name,
                naptr_iterate_init(&tried_bmp);
                while(dns_naptr_sip_iterate(
                                e->rr_lst, &tried_bmp, &srv_name, &n_proto)) {
-                       dns_srv_handle_init(h); /* make sure h does not contain 
garbage
+                       dns_srv_handle_reset(h); /* make sure h does not 
contain garbage
                                                                        from 
previous dns_srv_sip_resolve calls */
                        if((ret = dns_srv_resolve_ip(h, &srv_name, ip, port, 
flags)) >= 0) {
                                LM_DBG("(%.*s, %d, %d), srv0, ret=%d\n", 
name->len, name->s,
diff --git a/src/core/dns_cache.h b/src/core/dns_cache.h
index 18bb3733730..ce39c2a2b22 100644
--- a/src/core/dns_cache.h
+++ b/src/core/dns_cache.h
@@ -168,8 +168,9 @@ typedef unsigned long long srv_flags_t;
 
 struct dns_srv_handle
 {
-       struct dns_hash_entry *srv; /**< srv entry */
-       struct dns_hash_entry *a;       /**< a or aaaa current entry */
+       struct dns_hash_entry *naptr; /**< naptr entry */
+       struct dns_hash_entry *srv;       /**< srv entry */
+       struct dns_hash_entry *a;         /**< a or aaaa current entry */
 #ifdef DNS_SRV_LB
        srv_flags_t srv_tried_rrs;
 #endif
@@ -206,6 +207,10 @@ inline static void dns_srv_handle_put_helper(
                struct dns_srv_handle *h, const char *fpath, unsigned int line)
 {
        if(h) {
+               if(h->naptr) {
+                       dns_hash_put_entry(h->naptr, fpath, line);
+                       h->naptr = 0;
+               }
                if(h->srv) {
                        dns_hash_put_entry(h->srv, fpath, line);
                        h->srv = 0;
@@ -223,6 +228,8 @@ inline static void dns_srv_handle_put_helper(
 inline static void dns_srv_handle_ref(struct dns_srv_handle *h)
 {
        if(h) {
+               if(h->naptr)
+                       atomic_inc(&h->naptr->refcnt);
                if(h->srv)
                        atomic_inc(&h->srv->refcnt);
                if(h->a)
@@ -245,6 +252,10 @@ inline static void dns_srv_handle_cpy(
 inline static void dns_srv_handle_put_shm_unsafe(struct dns_srv_handle *h)
 {
        if(h) {
+               if(h->naptr) {
+                       dns_hash_put_shm_unsafe(h->naptr);
+                       h->naptr = 0;
+               }
                if(h->srv) {
                        dns_hash_put_shm_unsafe(h->srv);
                        h->srv = 0;
@@ -274,7 +285,7 @@ inline static int dns_srv_handle_next(struct dns_srv_handle 
*h, int err)
 
 inline static void dns_srv_handle_init(struct dns_srv_handle *h)
 {
-       h->srv = h->a = 0;
+       h->naptr = h->srv = h->a = 0;
        h->srv_no = h->ip_no = 0;
        h->port = 0;
        h->proto = 0;
@@ -283,6 +294,23 @@ inline static void dns_srv_handle_init(struct 
dns_srv_handle *h)
 #endif
 }
 
+inline static void dns_srv_handle_reset(struct dns_srv_handle *h)
+{
+       /* do NOT put the naptr */
+       if(h->srv) {
+               dns_hash_put(h->srv);
+               h->srv = 0;
+       }
+       if(h->a) {
+               dns_hash_put(h->a);
+               h->a = 0;
+       }
+       h->srv_no = h->ip_no = 0;
+       h->port = 0;
+#ifdef DNS_SRV_LB
+       h->proto = 0;
+#endif
+}
 
 /** @brief performes a srv query on name
  * Params:  name  - srv query target (e.g. _sip._udp.foo.bar)

_______________________________________________
Kamailio - Development Mailing List -- [email protected]
To unsubscribe send an email to [email protected]
Important: keep the mailing list in the recipients, do not reply only to the 
sender!

Reply via email to