[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