[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