Hello,

I've added support for the carrier ENUM setup as described in 
draft-haberler-carrier-enum-01.txt. This code is indended to
facilitate a trial. This certainly is not the final release as
the spec itself is in flux.

Anyway: please have a look and give me some indication whether
the patch could be incorporated into the default openser release.

cheers,

/ol
-- 
< Otmar Lendl ([EMAIL PROTECTED]) | nic.at Systems Engineer >
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/README 
sip-server/modules/enum/README
--- ser-orig/sip-server/modules/enum/README     2005-10-27 11:30:55.000000000 
+0200
+++ sip-server/modules/enum/README      2005-10-31 15:30:01.000000000 +0100
@@ -3,6 +3,8 @@
 
 Juha Heinanen
 
+Otmar Lendl
+
    Copyright © 2002, 2003 Juha Heinanen
      _________________________________________________________
 
@@ -15,13 +17,21 @@
 
               1.3.1. domain_suffix (string)
               1.3.2. tel_uri_params (string)
+              1.3.3. carrier_suffix (string)
+              1.3.4. branchlabel (string)
+              1.3.5. bl_algorithm (string)
 
         1.4. Exported Functions
 
               1.4.1. enum_query(),enum_query("suffix"),
                       enum_query("suffix", "service")
 
-              1.4.2. is_from_user_e164()
+              1.4.2.
+                      carrier_enum_query(),carrier_enum_query("suff
+                      ix"), carrier_enum_query("suffix",
+                      "service")
+
+              1.4.3. is_from_user_e164()
 
    2. Developer's Guide
    3. Frequently Asked Questions
@@ -29,24 +39,31 @@
    List of Examples
    1-1. Setting domain_suffix module parameter
    1-2. Setting tel_uri_params module parameter
-   1-3. enum_query usage
-   1-4. is_from_user_e164 usage
+   1-3. Setting carrier_suffix module parameter
+   1-4. Setting brachlabel module parameter
+   1-5. Zone file example
+   1-6. Setting the bl_algorithm module parameter
+   1-7. enum_query usage
+   1-8. is_from_user_e164 usage
      _________________________________________________________
 
 Chapter 1. User's Guide
 
 1.1. Overview
 
-   Enum module implements enum_query function that makes an enum
-   query based on the user part of the current Request-URI. The
-   function assumes that the user part consists of an
-   international phone number of the form +decimal-digits, where
-   the number of digits is at least 2 and at most 15. Out of this
-   number enum_query forms a domain name, where the digits are in
-   reverse order and separated by dots followed by domain suffix
-   that by default is "e164.arpa.". For example, if the user part
-   is +35831234567, the domain name will be
-   "7.6.5.4.3.2.1.3.8.5.3.e164.arpa.".
+   Enum module implements [carrier_]enum_query functions that
+   makes an enum query based on the user part of the current
+   Request-URI. The functions assumes that the user part consists
+   of an international phone number of the form +decimal-digits,
+   where the number of digits is at least 2 and at most 15. Out
+   of this number enum_query forms a domain name, where the
+   digits are in reverse order and separated by dots followed by
+   domain suffix that by default is "e164.arpa.". For example, if
+   the user part is +35831234567, the domain name will be
+   "7.6.5.4.3.2.1.3.8.5.3.e164.arpa.". carrier_enum_query
+   operates in a similar fashion. The only difference is that it
+   adds a label (default "carrier") to branch off from the
+   default, user-ENUM tree to a carrier ENUM tree.
 
    After forming the domain name, enum_query queries DNS for its
    NAPTR records. From the possible response enum_query chooses
@@ -126,6 +143,56 @@
 modparam("enum", "tel_uri_params", ";npdi")
      _________________________________________________________
 
+1.3.3. carrier_suffix (string)
+
+   The domain suffix to be used for carrier_enum_query() lookups.
+   Can be overridden by a parameter to carrier_enum_query.
+
+   Default value is "e164.arpa."
+
+   Example 1-3. Setting carrier_suffix module parameter
+modparam("enum", "carrier_suffix", "e1234.arpa.")
+     _________________________________________________________
+
+1.3.4. branchlabel (string)
+
+   This parameter determines which label carrier_enum_query()
+   will use to branch off the carrier ENUM tree.
+
+   Default value is ""carrier""
+
+   Example 1-4. Setting brachlabel module parameter
+modparam("enum", "branchlabel", "c")
+     _________________________________________________________
+
+1.3.5. bl_algorithm (string)
+
+   This parameter determines which algorithm carrier_enum_query()
+   will use to select the position in the DNS tree where the
+   carrier tree branches off the user ENUM tree.
+
+   If set to "cc", carrier_enum_query() will always inserts the
+   carrier label at the country-code level. Examples:
+   carrier.1.e164.arpa, carrier.3.4.e164.arpa,
+   carrier.2.5.3.e164.arpa
+
+   If set to "txt", carrier_enum_query() will look for a TXT
+   record at
+   [branchlabel].[reverse-country-code].[carrier_suffix] to
+   indicate after how many digits the carrier label should in
+   inserted.
+
+   Example 1-5. Zone file example
+carrier.1.e164.arpa.  IN      TXT     "4"
+9.9.9.8.7.6.5.carrier.4.3.2.1.e164.arpa. IN NAPTR "naptr content for  +
+1 234 5678 999"
+
+   Default value is "cc"
+
+   Example 1-6. Setting the bl_algorithm module parameter
+modparam("enum", "bl_algorithm", "txt")
+     _________________________________________________________
+
 1.4. Exported Functions
 
 1.4.1. enum_query(),enum_query("suffix"), enum_query("suffix",
@@ -142,7 +209,7 @@
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1-3. enum_query usage
+   Example 1-7. enum_query usage
 ...
 # search for "e2u+sip" in freenum.org
 enum_query("freenum.org.");
@@ -165,14 +232,28 @@
 ...
      _________________________________________________________
 
-1.4.2. is_from_user_e164()
+1.4.2. carrier_enum_query(),carrier_enum_query("suffix"),
+carrier_enum_query("suffix", "service")
+
+   The function performs an enum query and rewrites the
+   Request-URI with the result of the query. This the
+   carrier-ENUM version of enum_query(). The only difference to
+   enum_query() is in the calculation of the FQDN where NAPTR
+   records are looked for.
+
+   See
+   ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberl
+   er-carrier-enum-01.txt for the rationale behind this function.
+     _________________________________________________________
+
+1.4.3. is_from_user_e164()
 
    Checks if the user part of from URI an E164 number of the form
    +[0-9]{2,15}. Returns 1 if yes and -1 if not.
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1-4. is_from_user_e164 usage
+   Example 1-8. is_from_user_e164 usage
 ...
 if (is_from_user_e164()) {
         ....
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/doc/enum.sgml 
sip-server/modules/enum/doc/enum.sgml
--- ser-orig/sip-server/modules/enum/doc/enum.sgml      2005-06-13 
18:47:38.000000000 +0200
+++ sip-server/modules/enum/doc/enum.sgml       2005-10-28 18:44:52.000000000 
+0200
@@ -19,6 +19,11 @@
                <surname>Heinanen</surname>
                <email>[EMAIL PROTECTED]</email>
            </author>
+           <author>
+               <firstname>Otmar</firstname>
+               <surname>Lendl</surname>
+               <email>[EMAIL PROTECTED]</email>
+           </author>
        </authorgroup>
        <copyright>
            <year>2002</year>
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/doc/enum_user.sgml 
sip-server/modules/enum/doc/enum_user.sgml
--- ser-orig/sip-server/modules/enum/doc/enum_user.sgml 2005-10-27 
11:30:55.000000000 +0200
+++ sip-server/modules/enum/doc/enum_user.sgml  2005-10-31 15:07:29.000000000 
+0100
@@ -14,8 +14,8 @@
        <section id="sec-overview">
        <title>Overview</title>
        <para>
-               Enum module implements enum_query function that makes an enum 
query 
-               based on the user part of the current Request-URI. The function 
+               Enum module implements [carrier_]enum_query functions that 
makes an enum query 
+               based on the user part of the current Request-URI. The functions
                assumes that the user part consists of an international phone 
number 
                of the form +decimal-digits, where the number of digits is at
                least 2 and at most 15. Out of this number 
@@ -24,6 +24,9 @@
                domain suffix that by default is <quote>e164.arpa.</quote>. For 
example, 
                if the user part is +35831234567, the domain
                name will be <quote>7.6.5.4.3.2.1.3.8.5.3.e164.arpa.</quote>.
+               <function moreinfo="none">carrier_enum_query</function> 
operates in a similar
+               fashion. The only difference is that it adds a label (default 
"carrier")
+               to branch off from the default, user-ENUM tree to a carrier 
ENUM tree.
        </para>
        <para>
                After forming the domain name, 
@@ -130,6 +133,75 @@
 </programlisting>
                </example>
        </section>
+       <section>
+               <title><varname>carrier_suffix</varname> (string)</title>
+               <para>
+               The domain suffix to be used for carrier_enum_query() lookups.
+               Can be overridden by a parameter to carrier_enum_query.
+               </para>
+               <para>
+               Default value is <quote>e164.arpa.</quote>
+               </para>
+               <example>
+               <title>Setting carrier_suffix module parameter</title>
+               <programlisting format="linespecific">
+modparam("enum", "carrier_suffix", "e1234.arpa.")
+</programlisting>
+               </example>
+       </section>
+       <section>
+               <title><varname>branchlabel</varname> (string)</title>
+               <para>
+               This parameter determines which label carrier_enum_query() will 
use
+               to branch off the carrier ENUM tree.
+               </para>
+               <para>
+               Default value is <quote>"carrier"</quote>
+               </para>
+               <example>
+               <title>Setting brachlabel module parameter</title>
+               <programlisting format="linespecific">
+modparam("enum", "branchlabel", "c")
+</programlisting>
+               </example>
+       </section>
+
+       <section>
+               <title><varname>bl_algorithm</varname> (string)</title>
+               <para>
+               This parameter determines which algorithm carrier_enum_query() 
will use
+               to select the position in the DNS tree where the carrier tree 
+               branches off the user ENUM tree.
+               </para>
+               <para>
+               If set to "cc", carrier_enum_query() will always inserts the 
carrier 
+               label at the country-code level.
+               Examples: carrier.1.e164.arpa, carrier.3.4.e164.arpa, 
carrier.2.5.3.e164.arpa
+               </para>
+               <para>
+               If set to "txt", carrier_enum_query() will look for a TXT 
record at
+               [branchlabel].[reverse-country-code].[carrier_suffix] to 
indicate after how many digits the
+               carrier label should in inserted. 
+               <example>
+               <title>Zone file example</title>
+               <programlisting format="linespecific">
+carrier.1.e164.arpa.  IN      TXT     "4"
+9.9.9.8.7.6.5.carrier.4.3.2.1.e164.arpa. IN NAPTR "naptr content for  +1 234 
5678 999"
+</programlisting>
+               </example>
+               </para>
+               <para>
+               Default value is <quote>cc</quote>
+               </para>
+               <example>
+               <title>Setting the bl_algorithm module parameter</title>
+               <programlisting format="linespecific">
+modparam("enum", "bl_algorithm", "txt")
+</programlisting>
+               </example>
+       </section>
+
+
        </section>
 
        <section>
@@ -187,6 +259,22 @@
        </section>
 
        <section>
+               <title>
+               <function 
moreinfo="none">carrier_enum_query(),carrier_enum_query("suffix"), 
carrier_enum_query("suffix", "service")</function>
+               </title>
+               <para>
+               The function performs an enum query and rewrites the 
Request-URI with 
+               the result of the query. This the carrier-ENUM version of 
enum_query().
+               The only difference to enum_query() is in the calculation of the
+               FQDN where NAPTR records are looked for. 
+               </para>
+               <para>
+               See 
ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberler-carrier-enum-01.txt
+               for the rationale behind this function.
+               </para>
+       </section>
+
+       <section>
                <title><function 
moreinfo="none">is_from_user_e164()</function></title>
                <para>
                Checks if the user part of from <abbrev>URI</abbrev> an 
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/enum.c 
sip-server/modules/enum/enum.c
--- ser-orig/sip-server/modules/enum/enum.c     2005-09-05 12:32:05.000000000 
+0200
+++ sip-server/modules/enum/enum.c      2005-10-28 19:07:18.000000000 +0200
@@ -36,6 +36,78 @@
 #include "regexp.h"
 
 
+#define USER_ENUM 0
+#define CARRIER_ENUM 1
+
+
+/*
+ * Input: E.164 number w/o leading +
+ *
+ * Output: number of digits in the country code
+ *        0 on invalid number
+ *
+ * convention:
+ *   3 digits is the default length of a country code.
+ *   country codes 1 and 7 are a single digit.
+ *   the following country codes are two digits: 20, 27, 30-34, 36, 39,
+ *     40, 41, 43-49, 51-58, 60-66, 81, 82, 84, 86, 90-95, 98.
+ */
+static int cclen(const char *number)
+{
+       char d1,d2;
+
+       if (!number || (strlen(number) < 3))
+               return(0);
+
+       d1 = number[0];
+       d2 = number[1];
+       
+       if (!isdigit(d2)) 
+               return(0);
+
+       switch(d1) {
+               case '1':
+               case '7':
+                       return(1);
+               case '2':
+                       if ((d2 == '0') || (d1 == '7'))
+                               return(2);
+                       break;
+               case '3':
+                       if ((d2 >= '0') && (d1 <= '4'))
+                               return(2);
+                       if ((d2 == '6') || (d1 == '9'))
+                               return(2);
+                       break;
+               case '4':
+                       if (d2 != '2')
+                               return(2);
+                       break;
+               case '5':
+                       if ((d2 >= '1') && (d1 <= '8'))
+                               return(2);
+                       break;
+               case '6':
+                       if (d1 <= '6')
+                               return(2);
+                       break;
+               case '8':
+                       if ((d2 == '1') || (d1 == '2') || (d1 == '4') || (d1 == 
'6')) 
+                               return(2);
+                       break;
+               case '9':
+                       if (d1 <= '5')
+                               return(2);
+                       if (d2 == '8')
+                               return(2);
+                       break;
+               default:
+                       return(0);
+       }
+
+       return(3);
+}
+
 /* return the length of the string until c, if not found returns n */
 static inline int findchr(char* p, int c, unsigned int size)
 {
@@ -338,36 +410,71 @@
        *head = start;
 }      
 
-       
+
 /*
- * Call enum_query_2 with module parameter suffix and default service.
+ * Call enum_query_3 with module parameter suffix and default service.
  */
 int enum_query_0(struct sip_msg* _msg, char* _str1, char* _str2)
 {
-       return enum_query_2(_msg, (char *)(&suffix), (char *)(&service));
+       return enum_query_3(_msg, (char *)(&suffix), (char *)(&service), 
USER_ENUM);
 }
 
 /*
- * Call enum_query_2 with given suffix and default service.
+ * Call enum_query_3 with given suffix and default service.
  */
 int enum_query_1(struct sip_msg* _msg, char* _suffix, char* _str2)
 {
-       return enum_query_2(_msg, _suffix, (char *)(&service));
+       return enum_query_3(_msg, _suffix, (char *)(&service), USER_ENUM);
+}
+
+/*
+ * Call enum_query_3 with given suffix and service.
+ */
+int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
+{
+       return enum_query_3(_msg, _suffix, _service, USER_ENUM);
+}
+
+/*
+ * Call enum_query_3 with default suffix and service.
+ */
+int c_enum_query_0(struct sip_msg* _msg, char* _suffix, char* _service)
+{
+       return enum_query_3(_msg, (char *)(&c_suffix), (char *)(&service), 
CARRIER_ENUM);
+}
+
+/*
+ * Call enum_query_3 with given suffix and default service.
+ */
+int c_enum_query_1(struct sip_msg* _msg, char* _suffix, char* _service)
+{
+       return enum_query_3(_msg, _suffix, (char *)(&service), CARRIER_ENUM);
+}
+
+
+/*
+ * Call enum_query_3 with given suffix and service.
+ */
+int c_enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
+{
+       return enum_query_3(_msg, _suffix, _service, CARRIER_ENUM);
 }
 
 /*
  * See documentation in README file.
  */
 
-int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
+int enum_query_3(struct sip_msg* _msg, char* _suffix, char* _service, int 
carrier_flag)
 {
        char *user_s;
        int user_len, i, j, first;
        char name[MAX_DOMAIN_SIZE];
+       char apex[MAX_DOMAIN_SIZE];
        char uri[MAX_URI_SIZE];
        char new_uri[MAX_URI_SIZE];
        unsigned int priority, curr_prio;
        qvalue_t q;
+       int sdl = 0;    /* subdomain location: carrier enum offset */
 
        struct rdata* head;
        struct rdata* l;
@@ -395,18 +502,78 @@
        user_s = _msg->parsed_uri.user.s;
        user_len = _msg->parsed_uri.user.len;
 
+       /* make sure we don't run out of space */
+       if (( 2*user_len + c_branchlabel.len + suffix->len + 3) > 
MAX_DOMAIN_SIZE) {
+               LOG(L_ERR, "enum_query_3(): strings too long\n");
+               return -1;
+       }
+
        memcpy(&(string[0]), user_s, user_len);
        string[user_len] = (char)0;
 
+       /* default suffix from args */
+       memcpy(apex,  suffix->s , suffix->len);
+       apex[suffix->len] = (char)0;
+
+       /* Do the carrier-enum stuff */
+       if (carrier_flag == CARRIER_ENUM) {
+               int cc_len;
+/*             LOG(L_ERR, "enum_query(): DOING carrier ENUM\n"); */
+
+               cc_len = cclen(string + 1);
+
+               if (!strncasecmp(c_bl_alg.s,"txt",c_bl_alg.len)) {
+                       sdl = cc_len; /* default */
+
+                       j = 0;
+                       memcpy(name, c_branchlabel.s, c_branchlabel.len);
+                       j += c_branchlabel.len;
+                       name[j++] = '.';
+
+                       for (i = cc_len ; i > 0; i--) {
+                               name[j++] = user_s[i];
+                               name[j++] = '.';
+                       }
+                       memcpy(name + j, suffix->s, suffix->len + 1);
+                       head = get_record(name, T_TXT);
+                       if (head == 0) {
+                               DBG("enum_query(): No TXT found for %s\n",name);
+                       } else {
+                               sdl = atoi(((struct 
txt_rdata*)head->rdata)->txt);
+                               DBG("enum_query(): TXT record for %s is %d.\n", 
name, sdl);
+
+                               if ((sdl < 0) || (sdl > 5)) {
+                                       LOG(L_ERR, "enum_query(): sdl %d out of 
bounds. set back to cc_len.\n",sdl);
+                                       sdl = cc_len;
+                               }
+                       }
+               } else {        /* defaults to CC */
+                       sdl = cc_len;
+               }
+
+               j = 0;
+               memcpy(apex, c_branchlabel.s, c_branchlabel.len);
+               j += c_branchlabel.len;
+               apex[j++] = '.';
+
+               for (i = sdl ; i > 0; i--) {
+                       apex[j++] = user_s[i];
+                       apex[j++] = '.';
+               }
+               memcpy(apex + j, suffix->s, suffix->len + 1);
+
+       }
+
        j = 0;
-       for (i = user_len - 1; i > 0; i--) {
+       for (i = user_len - 1; i > sdl; i--) {
                name[j] = user_s[i];
                name[j + 1] = '.';
                j = j + 2;
        }
 
-       memcpy(name + j, suffix->s, suffix->len + 1);
+       memcpy(name + j, apex, strlen(apex)+1);
 
+       DBG("enum_query(): DOING ENUM with %s\n",name);
        head = get_record(name, T_NAPTR);
 
        if (head == 0) {
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/enum.h 
sip-server/modules/enum/enum.h
--- ser-orig/sip-server/modules/enum/enum.h     2005-06-13 18:47:38.000000000 
+0200
+++ sip-server/modules/enum/enum.h      2005-10-28 16:26:29.000000000 +0200
@@ -46,6 +46,9 @@
 int enum_query_0(struct sip_msg* _msg, char* _str1, char* _str2);
 int enum_query_1(struct sip_msg* _msg, char* _suffix, char* _str2);
 int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service);
+int c_enum_query_0(struct sip_msg* _msg, char* _str1, char* _str2);
+int c_enum_query_1(struct sip_msg* _msg, char* _suffix, char* _str2);
+int c_enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service);
 
 
 #endif /* ENUM_H */
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/enum_mod.c 
sip-server/modules/enum/enum_mod.c
--- ser-orig/sip-server/modules/enum/enum_mod.c 2005-06-13 18:47:38.000000000 
+0200
+++ sip-server/modules/enum/enum_mod.c  2005-10-28 16:25:49.000000000 +0200
@@ -57,6 +57,10 @@
 char* domain_suffix = "e164.arpa.";
 char* tel_uri_params = "";
 
+char* branchlabel = "carrier";
+char* carrier_suffix = "e164.arpa.";
+char* bl_algorithm = "cc";
+
 
 /*
  * Internal module variables
@@ -65,6 +69,9 @@
 str param;
 str service;
 
+str c_suffix;
+str c_branchlabel;
+str c_bl_alg;
 
 /*
  * Exported functions
@@ -74,6 +81,9 @@
        {"enum_query",        enum_query_1,      1, str_fixup,  REQUEST_ROUTE},
        {"enum_query",        enum_query_2,      2, enum_fixup, REQUEST_ROUTE},
        {"is_from_user_e164", is_from_user_e164, 0, 0,          REQUEST_ROUTE},
+       {"carrier_enum_query",c_enum_query_0,    0, 0,          REQUEST_ROUTE},
+       {"carrier_enum_query",c_enum_query_1,    1, str_fixup,  REQUEST_ROUTE},
+       {"carrier_enum_query",c_enum_query_2,    2, enum_fixup, REQUEST_ROUTE},
        {0, 0, 0, 0, 0}
 };
 
@@ -84,10 +94,12 @@
 static param_export_t params[] = {
         {"domain_suffix", STR_PARAM, &domain_suffix},
         {"tel_uri_params", STR_PARAM, &tel_uri_params},
+        {"branchlabel", STR_PARAM, &branchlabel},
+        {"carrier_suffix", STR_PARAM, &carrier_suffix},
+        {"bl_algorithm", STR_PARAM, &bl_algorithm},
        {0, 0, 0}
 };
 
-
 /*
  * Module parameter variables
  */
@@ -115,6 +127,15 @@
 
        service.len = 0;
 
+       c_suffix.s = carrier_suffix;
+       c_suffix.len = strlen(carrier_suffix);
+
+       c_branchlabel.s = branchlabel;
+       c_branchlabel.len = strlen(branchlabel);
+
+       c_bl_alg.s = bl_algorithm;
+       c_bl_alg.len = strlen(bl_algorithm);
+
        return 0;
 }
 
diff -dur -x '*.d' ser-orig/sip-server/modules/enum/enum_mod.h 
sip-server/modules/enum/enum_mod.h
--- ser-orig/sip-server/modules/enum/enum_mod.h 2005-06-13 18:47:38.000000000 
+0200
+++ sip-server/modules/enum/enum_mod.h  2005-10-28 11:19:24.000000000 +0200
@@ -37,5 +37,9 @@
 extern str param;            /* str version of tel_uri_params */
 extern str service;          /* default (empty) service */
 
+extern str c_suffix;        /* suffix for carrier ENUM */
+extern str c_branchlabel;    /* the label branching off the carrier tree */
+extern str c_bl_alg;         /* how to know where to branch off */
+
 
 #endif /* ENUM_MOD_H */
diff -dur -x '*.d' ser-orig/sip-server/modules/msilo/README 
sip-server/modules/msilo/README
--- ser-orig/sip-server/modules/msilo/README    2005-10-11 16:45:06.000000000 
+0200
+++ sip-server/modules/msilo/README     2005-10-31 14:54:46.000000000 +0100
@@ -299,7 +299,7 @@
 
    Example 1-9. OpenSER config script - sample msilo usage
 ...
-# $Id: README,v 1.2 2005/10/07 11:43:51 anomarme Exp $
+# $Id: msilo.cfg,v 1.1.1.1 2005/06/13 16:47:40 bogdan_iancu Exp $
 #
 # MSILO usage example
 #
diff -dur -x '*.d' ser-orig/sip-server/resolve.c sip-server/resolve.c
--- ser-orig/sip-server/resolve.c       2005-08-08 23:48:08.000000000 +0200
+++ sip-server/resolve.c        2005-10-28 17:37:33.000000000 +0200
@@ -292,6 +292,40 @@
        return 0;
 }
 
+/* RFC1035:
+ *
+ * <character-string> is a single length octet followed by that number of 
characters.
+ * TXT-DATA        One or more <character-string>s.
+ *
+ * We only take the first string here.
+ */
+/* parses a TXT record into a txt_rdata structure */
+struct txt_rdata* dns_txt_parser( unsigned char* msg, unsigned char* end,
+                                                                         
unsigned char* rdata)
+{
+       struct txt_rdata* txt;
+       int len,max_len;
+       
+       txt=0;
+       txt=(struct txt_rdata*)local_malloc(sizeof(struct txt_rdata));
+       if(txt==0){
+               LOG(L_ERR, "ERROR: dns_txt_parser: out of memory\n");
+               goto error;
+       }
+
+       len = *rdata;
+       if (rdata + 1 + len >= end) goto error; /*  something fishy in the 
record */
+       if (len >= sizeof(txt->txt)) goto error; /* not enough space? */
+       memcpy(txt->txt, rdata+1, len);
+       txt->txt[len] = 0;              /* 0-terminate string */
+       return txt;
+
+error:
+       if (txt) local_free(txt);
+       return 0;
+}
+
+
 
 
 /* frees completely a struct rdata list */
@@ -459,6 +493,12 @@
                                *last=rd;
                                last=&(rd->next);
                                break;
+                       case T_TXT:
+                               rd->rdata=(void*) dns_txt_parser(buff.buff, 
end, p);
+                               if(rd->rdata==0) goto error_parse;
+                               *last=rd;
+                               last=&(rd->next);
+                               break;
                        default:
                                LOG(L_ERR, "WARNING: get_record: unknown type 
%d\n", rtype);
                                rd->rdata=0;
diff -dur -x '*.d' ser-orig/sip-server/resolve.h sip-server/resolve.h
--- ser-orig/sip-server/resolve.h       2005-08-08 23:48:08.000000000 +0200
+++ sip-server/resolve.h        2005-10-28 17:27:31.000000000 +0200
@@ -107,6 +107,12 @@
        char name[MAX_DNS_NAME];
 };
 
+/* txt rec. struct*/
+/* This is not strictly correct as TXT records *could* contain multiple 
strings. */
+struct txt_rdata {
+       char txt[MAX_DNS_NAME];
+};
+
 
 
 struct rdata* get_record(char* name, int type);
_______________________________________________
Devel mailing list
[email protected]
http://openser.org/cgi-bin/mailman/listinfo/devel

Reply via email to