[Serdev] enum patch for multiple services and compound naptrs

Klaus Darilion klaus.mailinglists at pernau.at
Sun Jun 26 09:44:33 UTC 2005


Hi all!

According to your tips I made a patch for the enum modul. With this 
patch it is possible to search for multiple service types in a single 
enum_query. It also allows to parse compound NAPTRs (e.g. 
E2U+sip+voice:sip+video:sip+sms:sip)

The patch is backwards compatible with the current syntax. To enable the 
compound matching, the service paramter in the enum_query must start 
with a + sign.

E.g.
  enum_query("e164.arpa.","voice") will still search for e2u+voice:sip

  enum_query("e164.arpa.","+voice:sip+sip") will search for 
e2u+voice:sip or e2u+sip. It will also handle compound NAPTRs, thus
  enum_query("e164.arpa.","+sip") will match e2u+voice:sip+sip+sms:sip

Is there a chance to get this into ser? It is fully backwards 
compatible. Regarding performance: The compound matching will only be 
done if it is configured and it is for sure faster than a second DNS 
query if someone needs to support IETF and ETSI style NAPTRs.

The current patch is against 0.9. If it will be accepted, I will make a 
patch for CVS-head extend the documentation too.

I don't mind code review ;-)

regards,
klaus

-------------- next part --------------
sip_router/modules/enum# cvs diff -u
cvs server: Diffing .
Index: enum.c
===================================================================
RCS file: /cvsroot/ser/sip_router/modules/enum/enum.c,v
retrieving revision 1.18
diff -u -r1.18 enum.c
--- enum.c      3 Dec 2004 19:09:32 -0000       1.18
+++ enum.c      26 Jun 2005 09:42:41 -0000
@@ -41,8 +41,23 @@
 #include "regexp.h"


+/* return the length of the string until c, if not found returns n */
+static inline int findchr(char* p, int c, unsigned int size)
+{
+  int len=0;
+
+  for(;len<size;p++){
+    if (*p==(unsigned char)c) {
+      return len;
+    }
+    len++;
+  }
+  return len;
+}
+
 /* Checks if NAPTR record has flag u and its services field
- * e2u+[service:]sip
+ * e2u+[service:]sip or
+ * e2u+service[+service[+service[+...]]]
  */
 static inline int sip_match( struct naptr_rdata* naptr, str* service)
 {
@@ -52,14 +67,48 @@
       (naptr->services_len == 7) &&
       ((strncasecmp(naptr->services, "e2u+sip", 7) == 0) ||
        (strncasecmp(naptr->services, "sip+e2u", 7) == 0));
-  } else {
+  } else if (service->s[0] != '+') {
     return (naptr->flags_len == 1) &&
       ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) &&
       (naptr->services_len == service->len + 8) &&
       (strncasecmp(naptr->services, "e2u+", 4) == 0) &&
       (strncasecmp(naptr->services + 4, service->s, service->len) == 0) &&
       (strncasecmp(naptr->services + 4 + service->len, ":sip", 4) == 0);
-  }
+  } else { /* handle compound NAPTRs and multiple services */
+    str bakservice, baknaptr; /* we bakup the str */
+    int naptrlen, len;        /* length of the extracted service */
+
+    /* RFC 3761, NAPTR service field must start with E2U+ */
+    if (strncasecmp(naptr->services, "e2u+", 4) != 0) {
+      return 0;
+    }
+    baknaptr.s   = naptr->services + 4; /* leading 'e2u+' */
+    baknaptr.len = naptr->services_len - 4;
+    for (;;) { /* iterate over services in NAPTR */
+      bakservice.s   = service->s + 1; /* leading '+' */
+      bakservice.len = service->len - 1;
+      naptrlen = findchr(baknaptr.s,'+',baknaptr.len);
+
+      for (;;) { /* iterate over services in enum_query */
+        len = findchr(bakservice.s,'+',bakservice.len);
+        if ((naptrlen == len ) && !strncasecmp(baknaptr.s , bakservice.s, len)) {
+          return 1;
+        }
+        if ( (bakservice.len -= len+1) > 0) {
+          bakservice.s += len+1;
+          continue;
+        }
+        break;
+      }
+      if ( (baknaptr.len -= naptrlen+1) > 0) {
+        baknaptr.s += naptrlen+1;
+        continue;
+      }
+      break;
+    }
+    /* no matching service found */
+    return 0;
+  }
 }


cvs server: Diffing doc


More information about the Serdev mailing list