[Devel] [patch] Carrier ENUM support according to draft-haberler-carrier-enum-01.txt

Otmar Lendl lendl at nic.at
Mon Oct 31 15:59:21 CET 2005


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 (lendl at nic.at) | nic.at Systems Engineer >
-------------- next part --------------
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>jh at song.fi</email>
 	    </author>
+	    <author>
+		<firstname>Otmar</firstname>
+		<surname>Lendl</surname>
+		<email>lendl at nic.at</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);


More information about the Devel mailing list