Hello,
Currently I have big troubles in the combination of PRESENCE /
PRESENCE_XML (/ PUA / PUA_USRLOC) with POSTGRESQL database. During last
days I've analyzed the output of Kamailio 3.0.2 and PostgreSQL (8.3)
database, running on Debian Lenny OS. Following items were found:
1) The default settings of 4 PGSQL tables after initializing the
database with "kamdbctl init" are not useful; the tables "PRESENTITY",
"PUA", "ACC" and "MISSED_CALLS" have wrong settings for "Not NULL"
characteristics of some columns. In detail following columns had to be
adapted manually in the database:
"acc" and "missed_calls" table : column "id" must allow "NULL" (remove
"Not Null" setting)
"presentity" table: the column "sender" must allow "NULL" (remove "Not
Null" setting)
"pua" table: the columns "extra_headers", "version", "remote_contact",
"contact" and "desired_expires" must allow "NULL" (remove "Not Null"
setting)
E.g.
883:4451: 0(7123) ERROR: db_postgres [km_dbase.c:428]: driver error:
PGRES_FATAL_ERROR, ERROR: null value in column "sender" violates
not-null constraint
1008:5057: 1(7134) ERROR: db_postgres [km_dbase.c:428]: driver error:
PGRES_FATAL_ERROR, ERROR: null value in column "extra_headers" violates
not-null constraint
1025:5078: 1(7134) ERROR: db_postgres [km_dbase.c:428]: driver error:
PGRES_FATAL_ERROR, ERROR: null value in column "version" violates
not-null constraint
I recommend adapting the script "utils/kamctl/postgres/presence-create.sql"!
2) I do not know if this has a direct influence on the problems I
have with presence, but the column "sender" in the table "presentity"
seems to be used only "half". When the pua_usrloc module is inserting an
entry into the table it does NOT insert a value for the column "sender".
However, when a query is sent for selecting information from this table,
the column "sender" is explicitly requested......
e.g.
INSERTION (no "sender" value is inserted):
Jun 18 20:15:01 TestKam /usr/sbin/kamailio[3151]: DEBUG: db_postgres
[km_dbase.c:149]: 0x826ba68 PQsendQuery(insert into presentity
(domain,username,event,etag,expires,body,received_time ) values
('192.168.150.11','116333','presence','a.1276884785.3151.1.0',1276885262,'<?xml
version="1.0"?>\\012<presence xmlns="urn:ietf:params:xml:ns:pidf"
xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model"
xmlns:rpid="urn:ietf:params:xml:ns:pidf:rpid"
xmlns:c="urn:ietf:params:xml:ns:pidf:cipid"
entity="116333(a)192.168.150.11">\\012 <tuple id="0x828d7d8">\\012
<status>\\012 <basic>open</basic>\\012 </status>\\012
</tuple>\\012</presence>\\012',1276884901)
<file:///%5C%5C012%3c%5Cpresence%3e%5C012%27,1276884901%29>)
SELECTION (a "sender" value is explicitly queried):
Jun 18 20:15:08 TestKam /usr/sbin/kamailio[3151]: DEBUG: db_postgres
[km_dbase.c:149]: 0x826ba68 PQsendQuery(select body,sender from
presentity where domain='192.168.150.11' AND username='116333' AND
event='presence' AND etag='a.1276884785.3151.1.0')
What does the column "sender" represent? In the presence description on
the Kamailio homepage (version 1.5) this column still is not included.
3) The next problem I have is, that the PIDF-body, which is stored
in the PGSQL database, seems to cause an error in the presence_xml
module and therefore no body is attached to the NOTIFY message. The
NOTIFY message contains a SIP header "Content-Type:
application/pidf+xml", but no PIDF-body is sent in this message. As
result of this SIP request the SIP user agent (= subscriber) is a little
bit confused..... I think that problem in general has something to do
with the "error" described in the new task from Friday June 18^th
(http://lists.sip-router.org/pipermail/sr-dev/2010-June/007865.html).
First I wondered, why this problem only occurred in case that a
(subscribed) user agent de-registers from Kamailio registrar server. But
I guess the NOTIFY message after registration of the user agent is
created without dependency on a PGSQL query (= generated with
information from memory). Another behaviour of the server was, that
(after emptying all related tables) the first registration /
de-registration flow didn't cause any error (both NOTIFY messages were
readable and contained a PIDF-body); only beginning at the second flow
the body could not be parsed. This was tested with SIPp sending
register/de-register messages in a period of 3 seconds.
The Kamailio error message looks like:
Jun 18 13:08:16 TestKam /usr/sbin/kamailio[3167]: ERROR: presence_xml
[notify_body.c:515]: while parsing xml body message
Jun 18 13:08:16 TestKam /usr/sbin/kamailio[3167]: ERROR: presence_xml
[notify_body.c:84]: while aggregating body
4) I don't know if the parser might be influenced by a WARNING that
is generated by the postgresql daemon whenever an entry into the
presentity table is done (including XML body). From Kamailio log output
I saw that the special characters "#011" and "#012" are included in the
XML body. I guess that is the octal notation of \t (horizontal tab) and
\n (newline).
However, postgresql generates an error message that looks like following:
/WARNING: nonstandard use of \\ in a string literal at character 162/
HINT: Use the escape string syntax for backslashes, e.g., E'\\'.
Maybe this has some influence on the parser problem, too. Because in
this version of Postgresql the parameter "standard_conforming_strings"
is implicitly on -- just for previous versions it could be set to off.
That means, that any backslash symbol (\) is interpreted as standard
character (no escape). Therefore the queried result of the database does
no longer include \n and \t.
As interim "solution" of this problem I changed to the MySQL database
instead of PostgreSQL. The "Not NULL" violation is the same, but MySQL
seems to ignore this violation. Also the XML body is stored in MySQL "as
wished" -- that means: all special characters are stored and the queried
body still contains it.
The modules "pua" and "pua_usrloc" are used for testing purposes only,
because the user agents send publish messages themselves. Therefore it
is not necessary using this module. But for some regression tests I used
a command line base user agent that does not support publish messages.
But the problem is the same -- independent from the user agent and where
the publish messages is generated.
Additionally I have attached a ZIP file that contains traces of the SIP
traffic to/from Kamailio and Kamailio internally (Publish) and two
excerpts of Kamailio syslog. The syslog excerpts are from two register /
de-register sequences, where the first sequence was okay and the second
one generated the parsing error. I haven't found any essential
difference that would clarify the different behaviour of Kamailio.
Please give me some comments to these problems ;-) I know, PostgreSQL is
only "second quality" for Kamailio, but it has some advantages against
MySQL, too.
Thanks in advance and regards,
Klaus Feichtinger
Module: sip-router
Branch: master
Commit: 9ef1e02ac525368577efeabfd650c8c102827e75
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9ef1e02…
Author: Ovidiu Sas <osas(a)voipembedded.com>
Committer: Ovidiu Sas <osas(a)voipembedded.com>
Date: Fri Jul 2 22:38:55 2010 -0400
modules_k: ratelimit - README file updated to reflect rl_drop() removal
---
modules_k/ratelimit/doc/ratelimit_admin.xml | 122 +++------------------------
1 files changed, 12 insertions(+), 110 deletions(-)
diff --git a/modules_k/ratelimit/doc/ratelimit_admin.xml b/modules_k/ratelimit/doc/ratelimit_admin.xml
index 438179e..718ebd0 100644
--- a/modules_k/ratelimit/doc/ratelimit_admin.xml
+++ b/modules_k/ratelimit/doc/ratelimit_admin.xml
@@ -43,7 +43,8 @@
...
if (is_method("INVITE|REGISTER|SUBSCRIBE") {
if (!rl_check()) {
- rl_drop();
+ append_to_reply("Retry-After: 5\r\n");
+ sl_send_reply("503","Limiting");
exit;
};
};
@@ -264,67 +265,6 @@ modparam("ratelimit", "pipe", "4:NETWORK:10000")
</programlisting>
</example>
</section>
- <section>
- <title><varname>reply_code</varname> (integer)</title>
- <para>
- The code of the reply sent by &kamailio; while limiting.
- </para>
- <para>
- <emphasis>
- Default value is 503.
- </emphasis>
-
- </para>
- <example>
- <title>Set <varname>reply_code</varname> parameter</title>
- <programlisting format="linespecific">
-...
-modparam("ratelimit", "reply_code", 505)
-...
-</programlisting>
- </example>
- <para>
- This value cant be modified at runtime using sercmd
- </para>
- <example>
- <title> Set <varname>reply_code</varname> parameter at runtime </title>
- <programlisting format="linespecific">
-
-sercmd cfg.set_now_int ratelimit reply_code 505
-
- </programlisting>
- </example>
- </section>
- <section>
- <title><varname>reply_reason</varname> (string)</title>
- <para>
- The reason of the reply sent by &kamailio; while limiting.
- </para>
- <para>
- <emphasis>
- Default value is "Server Unavailable".
- </emphasis>
- </para>
- <example>
- <title>Set <varname>reply_reason</varname> parameter</title>
- <programlisting format="linespecific">
-...
-modparam("ratelimit", "reply_reason", "Limiting")
-...
-</programlisting>
- </example>
- <para>
- This value cant be modified at runtime using sercmd
- </para>
- <example>
- <title> Set <varname>reply_reason</varname> parameter at runtime </title>
- <programlisting format="linespecific">
-
-sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
-
- </programlisting>
- </example>
- </section>
</section>
<section>
<title>Exported Functions</title>
@@ -360,7 +300,8 @@ sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
...
# perform queue/pipe match for current method
if (!rl_check()) {
- rl_drop();
+ append_to_reply("Retry-After: 5\r\n");
+ sl_send_reply("503","Limiting");
exit;
};
...
@@ -368,7 +309,8 @@ sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
# set int pvar to 1
$var(p) = 1;
if (!rl_check("$var(p)")) {
- rl_drop();
+ append_to_reply("Retry-After: 5\r\n");
+ sl_send_reply("503","Limiting");
exit;
};
...
@@ -376,7 +318,8 @@ sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
# set str pvar to 1
$var(p) = "1";
if (!rl_check("$var(p)") {
- rl_drop();
+ append_to_reply("Retry-After: 5\r\n");
+ sl_send_reply("503","Limiting");
exit;
};
...
@@ -412,62 +355,21 @@ sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
...
# perform queue/pipe match for current method
if (!rl_check_pipe()) {
- rl_drop();
+ append_to_reply("Retry-After: 5\r\n");
+ sl_send_reply("503","Limiting");
exit;
};
...
# use pipe no 1 for the current method
if (!rl_check_pipe("1") {
- rl_drop();
+ append_to_reply("Retry-After: 5\r\n");
+ sl_send_reply("503","Limiting");
exit;
};
...
</programlisting>
</example>
</section>
- <section>
- <title>
- <function moreinfo="none">rl_drop([[min ], max])</function>
- </title>
- <para>
- For the current request, a "503 - Server Unavailable" reply is sent back.
- The reply may or may not have a "Retry-After" header. If no parameter is given,
- there will be no "Retry-After" header. If only the
- <emphasis>max</emphasis> parameter is given, the
- reply will contain a "Retry-After: <emphasis>max</emphasis>" header. If both
- <emphasis>min</emphasis> and <emphasis>max</emphasis> params are given, the
- reply will contain a "Retry-After: <emphasis>random</emphasis>" header with
- <emphasis>random</emphasis> being a random value between the given min and max.
- </para>
- <para>Meaning of the parameters is as follows:</para>
- <itemizedlist>
- <listitem><para>
- <emphasis>min</emphasis> - the minimum value of "Retry-After" header.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>max</emphasis> - the maximum value of "Retry-After" header.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- This function can be used from REQUEST_ROUTE.
- </para>
- <example>
- <title><function>rl_drop</function> usage</title>
- <programlisting format="linespecific">
-...
- if (!rl_check()) {
- # send back a "503 - Server Unavailable"
- # with a "Retry-After: 5"
- rl_drop("5");
- exit;
- };
-...
-</programlisting>
- </example>
- </section>
</section>
<section>
> My guess is that it would be easy. The differences are mainly in
> exported callbacks and some missing or extra script functions.
> k version has the *challenge() functions (which were removed from ser,
> but could be re-added easily) and some pv stuff.
andrei,
i tried to add k compatible www_challenge/proxy_challenge functions to
modules_s/auth and it is not easy (at least for me). i created function
static inline int build_hf(struct sip_msg* msg, int stale, str* realm,
str* nonce, str* algorithm, int hftype, str* hf)
that just builds the hf str and then using it, it is easy to implement
current build_challenge_hf function:
int build_challenge_hf(struct sip_msg* msg, int stale, str* realm, str* nonce,
str* algorithm, int hftype)
{
str hf;
avp_value_t val;
if (build_hf(msg, stale, realm, nonce, algorithm, hftype, &hf)) {
val.s = hf;
if (add_avp(challenge_avpid.flags | AVP_VAL_STR, challenge_avpid.name,
val) < 0) {
ERR("auth: Error while creating attribute\n");
pkg_free(hf.s);
return -1;
}
pkg_free(hf.s);
return 0;
} else {
return -1;
}
}
but when i tried to implement k *_challenge functions using it, i was
not able to figure out how to create nonce parameter. also, qop is
module param in s auth.
-- juha
i have now converted k/auth_radius module to use the famed
s/auth module. all functionality of existing auth_radius is preserved
except for this:
If an empty string "" is used (as realm parameter) then the
server will generate it from the request. In case of REGISTER
requests To header
field domain will be used (because this header field
represents a user being registered), for all other messages
From header field domain will be used.
so the user needs to always give the realm ($td/$fd/...).
regarding s/auth module, there are differences in parameters as compared
to k auth module and www_challenge()/proxy_challenge() have been
replaced by digest_challenge avp. this will be shown in README example.
is it ok if i commit the changes or does anyone else care if i'm the
only radius user?
-- juha