Hi list,
I have a big problem with this. I have ser_head working with
freeradius 0.9.1 and radiusclint-ng. Everything looks like
working, ser start doesn´t give me any problem, I have
create a database with ser_mysql.sh create, and I have
configured a softphone X-Lite to check it all. But when it
makes the register, radius doesn´t look like accessing to
MySQL.
Please any help will be genial!!!
Gerard Sanz.
This is the ser response:
sip:~ # ser start
Listening on
udp: sip.mars.sol [192.168.10.2]:5060
tcp: sip.mars.sol [192.168.10.2]:5060
Aliases:
*: mars.sol:*
WARNING: no fork mode
stateless - initializing
0(0) Maxfwd module- initializing
textops - initializing
0(0) INFO: udp_init: SO_RCVBUF is initially 111616
0(0) INFO: udp_init: SO_RCVBUF is finally 223232
2(0) INFO: fifo process starting: 4630
2(4630) SER: open_uac_fifo: fifo server up
at /tmp/ser_fifo...
0(4625) REGISTER sip:sip.mars.sol
From:sip:laptop@sip.mars.sol To:sip:laptop@sip.mars.sol
0(4625) REGISTER: Authenticating user
0(4625) REGISTER: challenging user
This is the radius response:
rad_recv: Access-Request packet from host 127.0.0.1:32854,
id=99, length=195
User-Name = "laptop(a)mars.sol"
Digest-Attributes = "\n\010laptop"
Digest-Attributes = "\001\nmars.sol"
Digest-Attributes =
"\002*42adc7dfc79504c6f4aae461eb995f8889b49658"
Digest-Attributes = "\004\022sip:sip.mars.sol"
Digest-Attributes = "\003\nREGISTER"
Digest-Response = "4fcfd64bf5b67211395a084e4c978eba"
Service-Type = Sip-Session
Sip-Uri-User = "laptop"
NAS-IP-Address = 127.0.0.1
NAS-Port = 5060
rlm_eap: EAP-Message not found
rlm_digest: Converting Digest-Attributes to something
sane...
Digest-User-Name = "laptop"
Digest-Realm = "mars.sol"
Digest-Nonce =
"42adc7dfc79504c6f4aae461eb995f8889b49658"
Digest-URI = "sip:sip.mars.sol"
Digest-Method = "REGISTER"
rlm_digest: Adding Auth-Type = DIGEST
rlm_sql (sql): Reserving sql socket id: 1
rlm_sql_mysql: MYSQL check_error: 1146 received
rlm_sql_getvpdata: database query error
rlm_sql (sql): SQL query error; rejecting user
rlm_sql (sql): Released sql socket id: 1
this is my sql.conf from the radius server:
#
# Configuration for the SQL module, when using MySQL.
#
# The database schema is available at:
#
#
src/radiusd/src/modules/rlm_sql/drivers/rlm_sql_mysql/db_mysql.sql
#
# If you are using PostgreSQL, please use
'postgresql.conf', instead.
# If you are using Oracle, please use 'oracle.conf',
instead.
# If you are using MS-SQL, please use 'mssql.conf',
instead.
#
# $Id: sql.conf,v 1.26.4.1 2003/08/26 12:26:57
phampson Exp $
#
sql {
# Database type
# Current supported are: rlm_sql_mysql,
rlm_sql_postgresql,
# rlm_sql_iodbc, rlm_sql_oracle, rlm_sql_unixodbc,
rlm_sql_freetds
driver = "rlm_sql_mysql"
# Connect info
server = "localhost"
login = "ser"
password = "heslo"
# Database table configuration
radius_db = "ser"
and finally, this is my ser.cfg:
# ----------- global configuration parameters
------------------------
debug=3 # debug level (cmd line:
-dddddddddd)
fork=no
log_stderror=yes # (cmd line: -E)
/* Uncomment these lines to enter debugging mode
#debug=7
#fork=no
#log_stderror=yes
*/
listen=sip.mars.sol # IP address(es) or hostnames where
SER will listen for messages
port=5060 # IP port where SER will listen for
messages
alias=mars.sol # additional IP address(es) or
hostnames to satisfy the condition "uri==myself"
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
children=4
fifo="/tmp/ser_fifo"
fifo_db_url="mysql://ser:heslo@localhost/ser"
fifo_mode=0666
#
# ------------------ module loading
----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/local/ser_radius/lib/ser/modules/mysql.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/sl.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/tm.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/rr.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/usrloc.so"
loadmodule
"/usr/local/ser_radius/lib/ser/modules/registrar.so"
loadmodule
"/usr/local/ser_radius/lib/ser/modules/textops.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/uri.so"
# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/usr/local/ser_radius/lib/ser/modules/auth.so"
loadmodule
"/usr/local/ser_radius/lib/ser/modules/auth_db.so"
loadmodule
"/usr/local/ser_radius/lib/ser/modules/auth_radius.so"
loadmodule "/usr/local/ser_radius/lib/ser/modules/xlog.so"
#loadmodule "/usr/local/ser_radius/lib/ser/modules/acc.so"
# ----------------- setting module-specific parameters
---------------
# -- usrloc params --
# Uncomment this if you want to use SQL database
# for persistent storage and comment the previous line
modparam("usrloc", "db_mode", 2)
# -- auth params --
# Uncomment if you are using auth module
#
modparam("auth_radius", "radius_config",
"/usr/local/etc/radiusclient-ng/radiusclient.conf")
# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
# -- acc params --
#modparam("acc", "log_level", 1)
#modparam("acc", "radius_flag", 1)
# ------------------------- request routing logic
-------------------
# main routing logic
route{
xlog("L_INFO","%rm %ru From:%fu To:%tu\n");
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
break;
};
if (msg:len >= max_len ) {
sl_send_reply("513", "Message too big");
break;
};
# loose-route processing (grant Route routing if
route headers present)
if (loose_route())
{
xlog("L_INFO"," -->Request
loose_routed\n");
append_hf("P-hint: loose_routed by
biloxi-proxy \r\n");
t_relay();
break;
};
# record route if its a session (INVITE method)
if (method=="INVITE")
{
record_route();
};
#check if request-URI is an alias
lookup ("aliases");
#if request URI is numeric and starting with 1
forward to sip.mars.sol
if (uri=~"^sip:1[0-9]*")
{
forward("sip.mars.sol");
break;
};
# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy;
that's
# particularly good if upstream and downstream
entities
# use different transport protocol
if (!method=="REGISTER") record_route();
# subsequent messages withing a dialog should take
the
# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
break;
};
if (!uri==myself) {
# mark routing logic in request
append_hf("P-hint: outbound\r\n");
route(1);
break;
};
# if the request is for other domain use UsrLoc
# (in case, it does not work, use the following
command
# with proper names and addresses in it)
if (uri==myself) {
if (method=="REGISTER") {
log(1, "REGISTER: Authenticating
user\n");
# Uncomment this if you want to use digest authentication
if
(!radius_www_authorize("mars.sol")) {
log(1, "REGISTER:
challenging user\n");
www_challenge("mars.sol",
"0");
break;
};
save("location");
break;
};
if (method=="INVITE") {
log(1, "INVITE\n");
setflag(1);
/* set for accounting (the same
value as in log_flag!) */
};
if (method=="MESSAGE") {
log(1, "MESSAGE\n");
setflag(1);
/* set for accounting (the same
value as in log_flag!) */
};
if (method=="BYE" || method=="CANCEL") {
log (1, "BYE or CANCEL\n");
setflag(1);
};
lookup("aliases");
if (!uri==myself) {
append_hf("P-hint: outbound
alias\r\n");
route(1);
break;
};
# native SIP destinations are handled using
our USRLOC DB
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
break;
};
};
append_hf("P-hint: usrloc applied\r\n");
route(1);
}
route[1]
{
# send it out now; use stateful forwarding as it
works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}
Thank you very much. I hope somebody has had the same
problem before and could solve it.
Gerard
Have you checked the format of the config file?? It might be in DOS format and SER is not able to load it. Just to be sure you can use dos2unix command (I had some problem with some version in the sense that this command modified the permissions of the file upon converting....)
Hope it helps,
Samuel.
Unclassified.
>>> "Jesús M. Movilla" <jmms03(a)tid.es> 06/10/05 08:22AM >>>
Hi again,
I tried to startup SER deleting the first line of ser.cfg but it didn't work
(similar problem). However I installed the 0.8.14 SER version and there was
no problem in starting up the SER with the previous failing ser.cfg.
¿any other idea?
Thanks for your answers
Jesús
P.D.- The ser.cf used is included down here. I put comments on the proper
function (handle_subscription, for example) of 0.10. pa module version to
start it up properly with 0.8.14 version.
####################################################################
# global configuration parameters a
debug=7 # debug level (cmd line: -dddddddddd)
#fork=yes
#log_stderror=yes # (cmd line: -E)
#memlog=5 # memory debug log level
#log_facility=LOG_LOCAL0 # sets the facility used for logging (see
syslog(3))
/* Uncomment these lines to enter debugging mode */
fork=no
log_stderror=yes
check_via=no # (cmd. line: -v)
dns=no # (cmd. line: -r)
rev_dns=no # (cmd. line: -R)
#port=5060
#children=4
fifo="/tmp/ser_fifo"
#user=ser
#group=ser
#fifo_user=ser # owner of the ser fifo
#fifo_group=ser
#fifo_mode=0660 # fifo's permissions
#disable_core=yes #disables core dumping
#open_fd_limit=1024 # sets the open file descriptors limit
#mhomed=yes # usefull for multihomed hosts, small performance penalty
#disable_tcp=yes
#tcp_accept_aliases=yes # accepts the tcp alias via option (see NEWS)
#
# ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database
loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/pa.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"
# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
# ----------------- setting module-specific parameters ---------------
# -- usrloc params --
#modparam("usrloc", "db_mode", 0)
# Uncomment this if you want to use SQL database
# for persistent storage and comment the previous line
modparam("usrloc", "db_mode", 2)
# -- auth params --
# Uncomment if you are using auth module
#
modparam("auth_db", "calculate_ha1", yes)
#
# If you set "calculate_ha1" parameter to yes (which true in this config),
# uncomment also the following parameter)
#
modparam("auth_db", "password_column", "password")
# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)
# -- pa params --
#
#modparam("pa", "default_expires", 3600) #Set default_expires parameter
#modparam("pa", "default_priority_percentage", 50) #Set
default_priority_percentage parameter
#modparam("pa", "db_url", "mysql:ser:heslo@localhost/ser") #Set db_url
parameter
#modparam("pa", "pa_domain", "hi.inet") #Set pa_domain parameter
# ------------------------- request routing logic -------------------
# main routing logic
route{
# initial sanity checks -- messages with
# max_forwards==0, or excessively long requests
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
break;
};
if (msg:len >= max_len ) {
sl_send_reply("513", "Message too big");
break;
};
# we record-route all messages -- to make sure that
# subsequent messages will go through our proxy; that's
# particularly good if upstream and downstream entities
# use different transport protocol
if (!method=="REGISTER") record_route();
# subsequent messages withing a dialog should take the
# path determined by record-routing
if (loose_route()) {
# mark routing logic in request
append_hf("P-hint: rr-enforced\r\n");
route(1);
break;
};
#if (!uri=~"hi.inet" {
# mark routing logic in request
# append_hf("P-hint: outbound\r\n");
# route(1);
# break;
#};
# if the request is for other domain use UsrLoc
# (in case, it does not work, use the following command
# with proper names and addresses in it)
if (uri=~"hi.inet") {
if (method=="REGISTER") {
# Uncomment this if you want to use digest authentication
if (!www_authorize("hi.inet", "subscriber")) {
www_challenge("hi.inet", "0");
break;
};
save("location");
break;
};
lookup("aliases");
if (!uri=~"hi.inet") {
append_hf("P-hint: outbound alias\r\n");
route(1);
break;
};
if (method=="PUBLISH") {
if (!t_newtran()) {
log(1, "newtran error\n");
sl_reply_error();
};
#handle_publish("registrar");
break;
};
# native SIP destinations are handled using our USRLOC DB
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
break;
};
};
append_hf("P-hint: usrloc applied\r\n");
route(1);
}
route[1]
{
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}
_______________________________________________
Serusers mailing list
serusers(a)lists.iptel.org
http://lists.iptel.org/mailman/listinfo/serusers
Hi to all,
I would like to know the way to install SER with PUBLISH support in the pa module. I tried to compile the pa module from CVS version and inserted within the 0.8.14 version but it didn´t work:I obtained the following error when starting up:
load_module: could not open module </usr/local/lib/ser/modules/pa.so>: /usr/local/lib/ser/modules/pa.so: undefined symbol qm_free
I also tried compiling the whole CVS version (0.10.99) but when I start up I obtain the ERROR bad config file (1 errors). I also tried with the config file ser.cfg from the 0.8.14 version but I obtained the same error. So, could someone tell me how to proceed in order to have a SER server with a pa module implementing REGISTER, SUSBSCRIBE AND PUBLISH.
Thank you very much
Jesús M. Movilla
We are all aware of SER limitation due the fact it is *only* transaction
statefull at proxy level, any dialog support being missing. There are
many features/services which actually requires a dialog awareness, like
storing the information in the dialog creation stage, information which
will be used during the whole dialog existence.
The most urging example is NAT traversal, in dealing with the within the
dialog INVITEs (re-INVITEs). When processing the initial INVITE, the
proxy detects if the caller or callee is behind some NAT and fixes the
signalling and media parts - since not all the detection mechanism are
available for within the dialog requests (like usrloc), to be able to
fix correspondingly the sequential requests, the proxy must remember
that the original request was NAT processed.
There are many other cases where dialog awareness fixes or helps....it's
not my goal to make a list here....
The solution is to store additional dialog-related information in the
routing set, headers which show up in all sequential requests; by
routing set I would say the Route hdrs and RURI; the routing set is
build based on Record-Route and Contact hdrs.
So far, the way to go was using the Contact header (via parameters) as
carrier. In most of the cases works, but this mechanism is not RFC
reinforced - I had a talk with Juha and he found some phones which
actually ignore the Contact hdr parameters, which is perfect allowed by
RFC....Not to mention that which Contact hdr (UAC or UAS) appear in
routing info depends on the request direction (UAC->UAS or UAS->UAC) and
Record-Route parameters are re-infonced by RFC (see 12.1.1 UAS behavior)
So the next try is to add this information in the Record-Route header
inserted by the proxy. Within the dialog, this information can be found
(with no direction dependencies) in Route header (with or proxy address)...
And here is a patch for the RR module which adds this functionality:
1) adding parameters to Record-Route; since RR is inserted during req.
processing (as lump), no textops function can be apply to it. So use the
add_rr_param("param") function - it can be called also before or after
the record_route() call; I would say it's more convenient from scripting
point of view (no dependencies between doing record_route() and adding
params);
2) checking Route parameters: this could be done via textops, but it
would be dangerous -> you have to identify the Route header
corresponding to your proxy (which will be quite difficult to put as
regexp), So use check_route_param("regexp") function which will check
the proper Route parameters against the given regexp. Must be call after
loose_route().
Basic scenario (example):
UAC SER
PROXY UAS
------ INVITE ----------> record_route() ---------
INVITE -------->
add_rr_param(";foo=true")
----- reINVITE ---------> loose_route() --------
reINVITE ------->
check_route_param(";foo=true")
<---- reINVITE ---------- loose_route() <-------
reINVITE --------
check_route_param(";foo=true")
<-------- BYE ----------- loose_route() <--------- BYE
-----------
check_route_param(";foo=true")
The patch doesn't alter any of the previous functionality.
Jan take a look and let's put it on CVS.
bogdan
Index: modules/rr/loose.c
===================================================================
RCS file: /cvsroot/ser/sip_router/modules/rr/loose.c,v
retrieving revision 1.36
diff -u -r1.36 loose.c
--- modules/rr/loose.c 23 Feb 2005 17:16:05 -0000 1.36
+++ modules/rr/loose.c 15 Apr 2005 14:52:55 -0000
@@ -30,6 +30,8 @@
* ---------
* 2003-02-28 scratchpad compatibility abandoned (jiri)
* 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
+ * 2005-04-10 check_route_param() and all hooks for keeping reference to
+ * Route params added (bogdan)
*/
@@ -57,6 +59,10 @@
#define ROUTE_SUFFIX ">\r\n"
#define ROUTE_SUFFIX_LEN (sizeof(ROUTE_SUFFIX)-1)
+/* variables used to hook the param part of the local route -bogdan */
+static unsigned int routed_msg_id;
+static str routed_params = {0,0};
+
/*
* Test whether we are processing pre-loaded route set
@@ -511,12 +517,16 @@
if (is_myself(&puri.host, puri.port_no))
#endif
{
- /* if (enable_double_rr && is_2rr(&_ruri->params)) { */
- /* DBG("ras(): Removing 2nd URI of mine: '%.*s'\n", rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s)); */
+ /*if (enable_double_rr && is_2rr(&_ruri->params)) {
+ * DBG("ras(): Removing 2nd URI of mine: '%.*s'\n",
+ * rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s)); */
+ /* set the hooks for the params -bogdan */
+ routed_msg_id = _m->id;
+ routed_params = puri.params;
if (!rt->next) {
- /* No next route in the same header, remove the whole header
- * field immediately
- */
+ /* No next route in the same header, remove the whole header
+ * field immediately
+ */
if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
LOG(L_ERR, "after_strict: Cannot remove Route HF\n");
return RR_ERROR;
@@ -661,11 +671,15 @@
if (is_myself(&puri.host, puri.port_no))
#endif
{
- DBG("after_loose: Topmost route URI: '%.*s' is me\n", uri->len, ZSW(uri->s));
+ DBG("after_loose: Topmost route URI: '%.*s' is me\n",
+ uri->len, ZSW(uri->s));
+ /* set the hooks for the params -bogdan */
+ routed_msg_id = _m->id;
+ routed_params = puri.params;
if (!rt->next) {
- /* No next route in the same header, remove the whole header
- * field immediately
- */
+ /* No next route in the same header, remove the whole header
+ * field immediately
+ */
if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
LOG(L_ERR, "after_loose: Can't remove Route HF\n");
return RR_ERROR;
@@ -684,16 +698,16 @@
if (enable_double_rr && is_2rr(&puri.params)) {
if (!rt->next) {
- /* No next route in the same header, remove the whole header
- * field immediately
- */
+ /* No next route in the same header, remove the whole header
+ * field immediately
+ */
if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
LOG(L_ERR, "after_loose: Can't remove Route HF\n");
return RR_ERROR;
}
res = find_next_route(_m, &hdr);
if (res < 0) {
- LOG(L_ERR, "after_loose: Error while finding next route\n");
+ LOG(L_ERR,"after_loose: Error while finding next route\n");
return RR_ERROR;
}
if (res > 0) { /* No next route found */
@@ -783,3 +797,32 @@
}
}
}
+
+
+
+int check_route_param(struct sip_msg * msg, char *re, char *foo)
+{
+ regmatch_t pmatch;
+ char bk;
+
+ /* check if the hooked params belong to the same message */
+ if (routed_msg_id != msg->id)
+ return -1;
+
+ /* check if params are present */
+ if ( !routed_params.s || !routed_params.len )
+ return -1;
+
+ /* do the well-known trick to convert to null terminted */
+ bk = routed_params.s[routed_params.len];
+ routed_params.s[routed_params.len] = 0;
+ DBG("DEBUG:rr:check_route_param: params are <%s>\n", routed_params.s);
+ if (regexec( (regex_t*)re, routed_params.s, 1, &pmatch, 0)!=0) {
+ routed_params.s[routed_params.len] = bk;
+ return -1;
+ } else {
+ routed_params.s[routed_params.len] = bk;
+ return 1;
+ }
+}
+
Index: modules/rr/loose.h
===================================================================
RCS file: /cvsroot/ser/sip_router/modules/rr/loose.h,v
retrieving revision 1.3
diff -u -r1.3 loose.h
--- modules/rr/loose.h 24 Aug 2004 09:00:38 -0000 1.3
+++ modules/rr/loose.h 15 Apr 2005 14:52:56 -0000
@@ -40,4 +40,6 @@
int loose_route(struct sip_msg* _m, char* _s1, char* _s2);
+int check_route_param(struct sip_msg * msg, char *re, char *foo);
+
#endif /* LOOSE_H */
Index: modules/rr/record.c
===================================================================
RCS file: /cvsroot/ser/sip_router/modules/rr/record.c,v
retrieving revision 1.14
diff -u -r1.14 record.c
--- modules/rr/record.c 24 Aug 2004 09:00:38 -0000 1.14
+++ modules/rr/record.c 15 Apr 2005 14:52:56 -0000
@@ -29,6 +29,7 @@
* History:
* -------
* 2003-04-04 Extracted from common.[ch] (janakj)
+ * 2005-04-10 add_rr_param() function and all corresponing hooks added (bogdan)
*/
#include <string.h>
@@ -63,6 +64,22 @@
#define INBOUND 1 /* Insert inbound Record-Route */
#define OUTBOUND 0 /* Insert outbound Record-Route */
+#define RR_PARAM_BUF_SIZE 512
+
+static unsigned int last_rr_msg;
+
+/* RR suffix lump and offset - used for inserting RR params
+ * after RR was done; use a two values array for INBOUND and
+ * OUTBOUND RR -bogdan */
+static struct lump *rr_suffix_lump[2] = {0,0};
+static int rr_suffix_end_offset[2] = {0,0};
+
+/* RR param buffer - usd for storing RR param which are
+ * added before RR insertion -bogdan */
+static char rr_param_buf_ptr[RR_PARAM_BUF_SIZE];
+static str rr_param_buf = {rr_param_buf_ptr,0};
+static unsigned int rr_param_msg;
+
/*
* Extract username from the Request URI
@@ -104,16 +121,20 @@
{
char* prefix, *suffix, *crlf, *r2;
int suffix_len, prefix_len;
+ char *p;
prefix_len = RR_PREFIX_LEN + (user->len ? (user->len + 1) : 0);
prefix = pkg_malloc(prefix_len);
if (enable_full_lr) {
suffix_len = (_lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN) +
- ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);
+ ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0) +
+ rr_param_buf.len;
} else {
suffix_len = (_lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN) +
- ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);
+ ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0) +
+ rr_param_buf.len;
}
+ rr_suffix_end_offset[_inbound] = RR_SR_TERM_LEN;
suffix = pkg_malloc(suffix_len);
crlf = pkg_malloc(2);
@@ -145,21 +166,24 @@
#endif
prefix[RR_PREFIX_LEN + user->len] = '@';
}
-
+
+ p = suffix;
if (tag && tag->len) {
- memcpy(suffix, RR_FROMTAG, RR_FROMTAG_LEN);
- memcpy(suffix + RR_FROMTAG_LEN, tag->s, tag->len);
- if (enable_full_lr) {
- memcpy(suffix + RR_FROMTAG_LEN + tag->len, _lr ? RR_LR_FULL_TERM : RR_SR_TERM, _lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN);
- } else {
- memcpy(suffix + RR_FROMTAG_LEN + tag->len, _lr ? RR_LR_TERM : RR_SR_TERM, _lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN);
- }
+ memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
+ p += RR_FROMTAG_LEN;
+ memcpy(p, tag->s, tag->len);
+ p += tag->len;
+ }
+ if (rr_param_buf.len) {
+ memcpy( p, rr_param_buf.s, rr_param_buf.len);
+ p += rr_param_buf.len;
+ }
+ if (enable_full_lr) {
+ memcpy( p, _lr ? RR_LR_FULL_TERM : RR_SR_TERM,
+ _lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN);
} else {
- if (enable_full_lr) {
- memcpy(suffix, _lr ? RR_LR_FULL_TERM : RR_SR_TERM, _lr ? RR_LR_FULL_TERM_LEN : RR_SR_TERM_LEN);
- } else {
- memcpy(suffix, _lr ? RR_LR_TERM : RR_SR_TERM, _lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN);
- }
+ memcpy( p, _lr ? RR_LR_TERM : RR_SR_TERM,
+ _lr ? RR_LR_TERM_LEN : RR_SR_TERM_LEN);
}
memcpy(crlf, CRLF, 2);
@@ -177,6 +201,7 @@
r2 = 0;
}
if (!(_l2 = insert_new_lump_before(_l2, suffix, suffix_len, 0))) goto lump_err;
+ rr_suffix_lump[_inbound] = _l2;
suffix = 0;
if (!(_l2 = insert_new_lump_before(_l2, crlf, 2, 0))) goto lump_err;
crlf = 0;
@@ -225,6 +250,12 @@
tag = 0;
}
+ if (rr_param_buf.len && rr_param_msg!=_m->id) {
+ /* rr_params were set for a different message -> reset buffer */
+ rr_param_buf.len = 0;
+ DBG("----> reset rr_param_buf\n");
+ }
+
if (enable_double_rr) {
l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
@@ -256,6 +287,8 @@
return -4;
}
+ /* reset the rr_param buffer */
+ rr_param_buf.len = 0;
return 0;
}
@@ -266,8 +299,6 @@
*/
static inline int do_RR(struct sip_msg* _m, int _lr)
{
- static unsigned int last_rr_msg;
-
if (_m->id == last_rr_msg) {
LOG(L_ERR, "record_route(): Double attempt to record-route\n");
return -1;
@@ -395,3 +426,72 @@
{
return do_RR(_m, 0);
}
+
+
+/*
+ * Appends a string to an existent lump
+ */
+static inline int append_to_lump( struct lump *l, str *s, int end_offset)
+{
+ char *p;
+
+ /* update buffer */
+ p = pkg_realloc( l->u.value, l->len+s->len);
+ if (p==0) {
+ LOG(L_ERR,"ERROR:rr:add_rr_param: no more pkg memory\n");
+ return -1;
+ }
+ memmove(p+l->len-end_offset+s->len, p+l->len-end_offset, end_offset);
+ memcpy( p+l->len-end_offset, s->s, s->len);
+ /* update lump structure */
+ l->len += s->len;
+ l->u.value = p;
+ return 0;
+}
+
+
+/*
+ * Appends a new Record-Route parameter
+ */
+int add_rr_param(struct sip_msg* msg, char* param, char* foo)
+{
+ str *rr_param;
+ int i;
+
+ rr_param = (str*)param;
+
+ if (last_rr_msg==msg->id) {
+ /* RR was already done -> have to modify the RR-sufix lump */
+ for( i=OUTBOUND ; i<=INBOUND ; i++ ) {
+ if ( !rr_suffix_lump[i] || !rr_suffix_end_offset[i] )
+ continue;
+ if (append_to_lump( rr_suffix_lump[i], rr_param,
+ rr_suffix_end_offset[i])!=0) {
+ LOG(L_ERR,"ERROR:rr:add_rr_param: failed to update lump\n");
+ goto error;
+ }
+ }
+ } else {
+ /* RR not done yet -> store the param in the static buffer */
+ if (rr_param_msg!=msg->id) {
+ /* it's about a different messge -> reset buffer */
+ rr_param_buf.len = 0;
+ rr_param_msg = msg->id;
+ }
+ if (rr_param_buf.len+rr_param->len>RR_PARAM_BUF_SIZE) {
+ LOG(L_ERR,"ERROR:rr:add_rr_param: maximum size of "
+ "rr_param_buf exceeded\n");
+ goto error;
+ }
+ memcpy( rr_param_buf.s+rr_param_buf.len, rr_param->s, rr_param->len);
+ rr_param_buf.len += rr_param->len;
+ DBG("DEBUG:rr:add_rr_param: rr_param_buf=<%.*s>\n",rr_param_buf.len,
+ rr_param_buf.s);
+ }
+ return 1;
+
+error:
+ return -1;
+}
+
+
Index: modules/rr/record.h
===================================================================
RCS file: /cvsroot/ser/sip_router/modules/rr/record.h,v
retrieving revision 1.2
diff -u -r1.2 record.h
--- modules/rr/record.h 24 Aug 2004 09:00:38 -0000 1.2
+++ modules/rr/record.h 15 Apr 2005 14:52:56 -0000
@@ -56,4 +56,10 @@
int record_route_strict(struct sip_msg* _m, char* _s1, char* _s2);
+/*
+ * Appends a new Record-Route parameter
+ */
+int add_rr_param(struct sip_msg* msg, char* param, char* foo);
+
+
#endif /* RECORD_H */
Index: modules/rr/rr_mod.c
===================================================================
RCS file: /cvsroot/ser/sip_router/modules/rr/rr_mod.c,v
retrieving revision 1.33
diff -u -r1.33 rr_mod.c
--- modules/rr/rr_mod.c 24 Aug 2004 09:00:38 -0000 1.33
+++ modules/rr/rr_mod.c 15 Apr 2005 14:52:57 -0000
@@ -33,11 +33,14 @@
* 2003-03-19 all mallocs/frees replaced w/ pkg_malloc/pkg_free (andrei)
* 2003-04-01 Added record_route with ip address parameter (janakj)
* 2003-04-14 enable_full_lr parameter introduced (janakj)
+ * 2005-04-10 add_rr_param() and check_route_param() added (bogdan)
*/
#include <stdio.h>
#include <stdlib.h>
+#include <regex.h>
+
#include "../../sr_module.h"
#include "../../ut.h"
#include "../../error.h"
@@ -61,6 +64,7 @@
static int mod_init(void);
static int str_fixup(void** param, int param_no);
+static int regexp_fixup(void** param, int param_no);
/*
@@ -74,10 +78,18 @@
* Oh, BTW, have I mentioned already that you shouldn't use strict routing ?
*/
static cmd_export_t cmds[] = {
- {"loose_route", loose_route, 0, 0, REQUEST_ROUTE},
- {"record_route", record_route, 0, 0, REQUEST_ROUTE},
- {"record_route_preset", record_route_preset, 1, str_fixup, REQUEST_ROUTE},
- {"record_route_strict" , record_route_strict, 0, 0, 0 },
+ {"loose_route", loose_route, 0, 0,
+ REQUEST_ROUTE},
+ {"record_route", record_route, 0, 0,
+ REQUEST_ROUTE},
+ {"record_route_preset", record_route_preset, 1, str_fixup,
+ REQUEST_ROUTE},
+ {"record_route_strict" , record_route_strict, 0, 0,
+ 0},
+ {"add_rr_param", add_rr_param, 1, str_fixup,
+ REQUEST_ROUTE},
+ {"check_route_param", check_route_param, 1, regexp_fixup,
+ REQUEST_ROUTE},
{0, 0, 0, 0, 0}
};
@@ -149,3 +161,29 @@
return 0;
}
+
+
+static int regexp_fixup(void** param, int param_no)
+{
+ regex_t* re;
+
+ if (param_no==1) {
+ if ((re=pkg_malloc(sizeof(regex_t)))==0) {
+ LOG(L_ERR,"ERROR:rr:regexp_fixup: no more pkg memory\n");
+ return E_OUT_OF_MEM;
+ }
+ if (regcomp(re, *param, REG_EXTENDED|REG_ICASE|REG_NEWLINE) ) {
+ pkg_free(re);
+ LOG(L_ERR, "ERROR:rr:regexp_fixup: bad regexp %s\n",(char*)*param);
+ return E_BAD_RE;
+ }
+ /* free string */
+ pkg_free(*param);
+ /* replace it with the compiled re */
+ *param=re;
+ }
+ return 0;
+}
+
+
+
On Thursday 09 June 2005 05:07 am, you wrote:
> Just my 2 cents....
>
> Since SER is transaction aware and not dialog aware, it is not easy to maintain consistent Cseq values during a dialog. I'm sure UAC maintainers are thinking on it and they will come with a solution, but just let them work without stress ;)
Sure. I didn't want to put stress on anyone.
However I proposed a way to implement it by existing (or simple to add) means.
Not that I liked it too much myself, but that is the only thing I could come with and
I'd really like to receive some comments on whether it's possible or I'm
completely wrong.
Also I'm wondering how hard is it to have something like "save_dialog()" and "check_dialog()"
function that would store callid and from/to tag in some in-memory hash.
I don't think that performance/memory consumption objections really stands anymore.
How much memory would it take to save dialog identifier (callid and tags)?
Let's say 100 bytes. So if I dedicate 10M of RAM for that table I'd be able
to keep 100000 dialogs.
> However, don't think the UAC approach is the right one having TLS around......I would prefer pushing for TLS instead of adding a table of existing dialog in SER with the appropriate values. I'm sure there's lots of providers reading this list so if everybody starts asking for TLS....well, big providers will start providing it for auth. I'm not an expert but I've been told implementing TLS is not a hard job....;)
Well, if TLS becomes mainstream I'll have no choice, but use it,
but I'd prefer to do without TLS or even moving to TCP, at least for a while.
I believe existing md5 authentication is good enough for what it is used
in SIP. Sure setting TLS is doable, but it's definitely more work
then just setting shared password.
Also I don't think TLS is going to become mainstream in SIP any time soon.
Look at TLS in SMTP. It's been available for years, but I still don't see it in
wide use for server-to-server communication, just between servers and end users.
>
> Samuel.
>
>
> Unclassified.
> >>> "Greger V. Teigre" <greger(a)teigre.com> 06/09/05 07:18AM >>>
>
> Michael Ulitskiy wrote:
> > Greg, do you really believe that avoiding added, but optional
> > complexity
> > is good enough reason for not having IMHO necessary functionality?
>
> Not at all. My point was that it is extremely important to add functionality
> where it belongs logically and where you can ensure that regular ser.cfg
> users are able to use the functionality without understanding the specs.
>
> > Again, IMHO, having something better than ip auth is a must in
> > today's internet.
>
> Again, I agree.
>
> > On the subject:
> > I guess the reason is, as I said before, that not only cseq in
> > original invite must be incremented, but cseq in all subsequent
> > in-dialog messages must
> > be adjusted (decremented for messages relayed to callee and
> > incremented
> > for messages relayed to called party). That is what, I guess, is hard
> > to do in today's ser.
> > I've posted my thoughts on how it possibly could be accomplished
> > at http://lists.iptel.org/pipermail/serdev/2005-May/004589.html and
> > haven't received any feedback or comments.
> > I guess either there's a lack of interest for getting it to work
> > which I guess is really strange or it's too hard to implement at
> > current stage.
> > As always any comments are welcome :)
>
> I don't think it's a lack of interest or lack of need for it. All the
> developers are bombarded with requests and have long lists of core things to
> do. Sometimes its even hard to get them to evaluate and include patches in
> CVS.
> IMHO, increment cseq belongs in the UAC module (can do far too much harm
> if users play around with it). If you cannot get the maintainers attention,
> there is only one way: Get your hands dirty ;-)
>
> g-)
>
> _______________________________________________
> Serdev mailing list
> serdev(a)lists.iptel.org
> http://lists.iptel.org/mailman/listinfo/serdev
>
>
Hello,
is there a simple method to increment CSeq of a branch?
I have the following in failure_route:
if (uac_auth()) {
# mark that auth was performed
setflag(7);
# trigger again the failure route
t_on_failure("3");
# repeat the request with auth response
append_branch();
----------> and here I'd like to increment CSeq
t_relay();
}
If CSeq is not incremented, this authenticated request does not work
with RFC strict UAs, as discussed eg in this
(http://lists.iptel.org/pipermail/serusers/2005-May/019806.html) thread.
Now as I want to proxy auth an INVITE I am sending myself from sems I
could do a dirty workaround: assume that the INVITE needs two CSeqs and
increment cseq a second time for subsequent requests in sems. This is of
course a hack but would save me from implementing auth in sems for the
moment.
Thanks for any suggestions
Stefan
Hi,
on the calls made page it shows less actual results than the number
shown in the page links. For example, on page 1 it says showing 1-20 of
83 but if i go through each page, from page 4 onwards they are blank.
Had a quick check with the query and it was returning 50 calls made. Any
ideas? Also, the calls made seems to be made up of the same calls but
broken down into segments - ie there are 4 rows for what seems like 1
call.
Cam.
--
--
|Cameron Black Broadband Solutions for
|Application Developer Home & Business @
|PlusNet plc. www.plus.net
+------ PlusNet - The smarter way to Internet! -----
I can call SER with a phone registered to it, no problem.
When i try to make outbound calls to my provider, they fail with.
407 - proxy authentication required.
I cant seem to trace it down:
if (method=="REGISTER") {
# Uncomment this if you want to use digest
authentication
if (!www_authorize("sr.mydomain.com", "subscriber")) {
www_challenge("sr.mydomain", "0");
break;
};
save("aliases");
save("location");
break;
};
Is this a problem at my end or my providers?
I am new to SER, is there something i am missing?
Thanks.