Anthony Messina 9e1ff4488a all: updated FSF address in GPL text 11 yıl önce
..
doc db6762f45e uid_avp_db: Fix TOC in documentation 12 yıl önce
Makefile 1316bb1cd4 modules_s/uid_avp_db: moved to modules folder 12 yıl önce
README 0577abba2a documentation: Rebuild all modified READMEs 12 yıl önce
avp_db.xml 1316bb1cd4 modules_s/uid_avp_db: moved to modules folder 12 yıl önce
extra_attrs.c 1316bb1cd4 modules_s/uid_avp_db: moved to modules folder 12 yıl önce
extra_attrs.h 1316bb1cd4 modules_s/uid_avp_db: moved to modules folder 12 yıl önce
uid_avp_db.c 9e1ff4488a all: updated FSF address in GPL text 11 yıl önce
uid_avp_db.h 9e1ff4488a all: updated FSF address in GPL text 11 yıl önce

README


UID AVP DB Module

Jiri Kuthan

FhG FOKUS


Copyright � 2004, 2005 FhG FOKUS
_________________________________________________________________

Table of Contents

1. Admin Guide

1. Overview
2. Dependencies
3. Parameters

3.1. db_url (string)
3.2. user_attrs_table (string)
3.3. uri_attrs_table (string)
3.4. uid_column (string)
3.5. username_column (string)
3.6. did_column (string)
3.7. name (string)
3.8. value_column (string)
3.9. type_column (string)
3.10. flags_column (string)
3.11. scheme_column (string)
3.12. attr_group (string)
3.13. auto_unlock_extra_attrs (string)

4. Functions

4.1. load_attrs (track, id)
4.2. load_extra_attrs (group_id, id)
4.3. save_extra_attrs (group_id, id)
4.4. remove_extra_attrs (group_id, id)
4.5. lock_extra_attrs (group_id, id)
4.6. unlock_extra_attrs (group_id, id)

5. Example extra attributes usage

List of Examples

1.1. attribute group definition

Chapter 1. Admin Guide

Table of Contents

1. Overview
2. Dependencies
3. Parameters

3.1. db_url (string)
3.2. user_attrs_table (string)
3.3. uri_attrs_table (string)
3.4. uid_column (string)
3.5. username_column (string)
3.6. did_column (string)
3.7. name (string)
3.8. value_column (string)
3.9. type_column (string)
3.10. flags_column (string)
3.11. scheme_column (string)
3.12. attr_group (string)
3.13. auto_unlock_extra_attrs (string)

4. Functions

4.1. load_attrs (track, id)
4.2. load_extra_attrs (group_id, id)
4.3. save_extra_attrs (group_id, id)
4.4. remove_extra_attrs (group_id, id)
4.5. lock_extra_attrs (group_id, id)
4.6. unlock_extra_attrs (group_id, id)

5. Example extra attributes usage

1. Overview

This module contains several functions that can be used to manipulate
the contents of AVPs (Attribute-Value pairs). The AVPs are variables
attached to the SIP message being processed. Each variable has its
name and value. AVPs can be used to store arbitrary data or as a means
of inter-module comminication.

You may also want to check the avpops module which is more flexible
and contains more functions. In future SER releases the avp module
will be probably deprecated in favor of avpops module.

Domain module operates in caching mode. Domain module reads the
default values of AVPs into cache memory when the module is loaded.
After that default values is re-read only when module is given
avp_list_reload fifo command. Any changes in usr_preferences_types
table must thus be followed by avp_list_reload command in order to
reflect them in module behavior.

2. Dependencies

A database module, such as mysql, postgres, or dbtext.

3. Parameters

3.1. db_url (string)
3.2. user_attrs_table (string)
3.3. uri_attrs_table (string)
3.4. uid_column (string)
3.5. username_column (string)
3.6. did_column (string)
3.7. name (string)
3.8. value_column (string)
3.9. type_column (string)
3.10. flags_column (string)
3.11. scheme_column (string)
3.12. attr_group (string)
3.13. auto_unlock_extra_attrs (string)

3.1. db_url (string)

The URL of the database to be used.

Default value is "mysql://ser:heslo@localhost/ser".

3.2. user_attrs_table (string)

Name of the table with user attributes.

Default value is "user_attrs".

3.3. uri_attrs_table (string)

Name of the table with uri attributes.

Default value is "uri_attrs".

3.4. uid_column (string)

Name of the column that stores UID in the user attributes table.

Default value is "uid".

3.5. username_column (string)

Name of the column containing the username of the subscriber in uri
attributes table.

Default value is "username".

3.6. did_column (string)

Name of the column in uri attributes table containing the ID of domain
that the subscriber belongs to.

Default value is "did".

3.7. name (string)

The name of the column containing attribute names.

Default value is "name".

3.8. value_column (string)

The name of the column containing attribute values.

Default value is "value".

3.9. type_column (string)

The name of the column containing attribute value type.

Default value is "type".

3.10. flags_column (string)

The name of the column containing attribute flags.

Default value is "flags".

3.11. scheme_column (string)

The name of the column containing subscriber's scheme in uri
attributes.

Default value is "scheme".

3.12. attr_group (string)

'Extra attribute' group definition. It can be repeated to define more
attribute groups.

The group definition contains one or more assignments in the form
key=value. Possible keys are:

id
Attribute group identifier. Must be set.

table
Table name used for storing attributes from this attribute
group. Must be set.

flag
Attribute flag name used to mark attributes in this group. Must
be set.

key_column
Column name holding key. Default value is "id".

name_column
Column name used for storing attribute name. Default value is
"name".

value_column
Column name used for storing attribute value. Default value is
"value".

type_column
Column name used for storing attribute type. Default value is
"type".

flags_column
Column name used for storing attribute flags. Default value is
"flags".

None defined by default.

Example 1.1. attribute group definition
modparam("avp_db", "attr_group", "id=dlg,flag=dialog_flag,table=dlg_attrs,key_c
olumn=dlg_id");

Table used for these attributes:
mysql> describe dlg_attrs;
+--------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------------+------+-----+---------+-------+
| dlg_id | varchar(256) | NO | MUL | | |
| name | varchar(32) | NO | | | |
| value | varchar(255) | YES | | NULL | |
| type | int(11) | NO | | 0 | |
| flags | int(10) unsigned | NO | | 0 | |
+--------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

Setting flags from code (all attrs beginning with "dlg_"):
avpflags dialog_flag;
...
route {
...
setavpflag("$f./^dlg_/", "dialog_flag");
...
}

3.13. auto_unlock_extra_attrs (string)

Determines the action when any of the 'extra attributes' lock is
detected when routing script execution was finished. When the value of
this parameter is zero (default) BUG level message is logged, but the
lock is kept, so another process trying to obtain the lock might get
stuck. If the value is nonzero, DEBUG level message is sent to the log
and all the locks are released.

Default value is 0.

4. Functions

4.1. load_attrs (track, id)
4.2. load_extra_attrs (group_id, id)
4.3. save_extra_attrs (group_id, id)
4.4. remove_extra_attrs (group_id, id)
4.5. lock_extra_attrs (group_id, id)
4.6. unlock_extra_attrs (group_id, id)

4.1. load_attrs (track, id)

Loads attributes from the database.

track

$fu
Load user attributes into from track. In this case the
second parameter is UID used to search attributes.

$tu
Load user attributes into to track. In this case the
second parameter is UID used to search attributes.

$fr
Load uri attributes into from track. In this case the
second parameter is URI used to search attributes.

$tr
Load uri attributes into to track. In this case the
second parameter is URI used to search attributes.

id
Identifier used for searching attributes. When searching for
user attributes it is UID, when searchnig uri attributes it is
URI.

4.2. load_extra_attrs (group_id, id)

Loads 'extra attributes' stored by previous call to save_extra_attrs.

group_id
Identifies attribute group, see Section 3.12, "attr_group
(string)".

id
Identifies attributes which should be loaded.

4.3. save_extra_attrs (group_id, id)

Saves 'extra attributes' flagged by group flag under given id.

group_id
Identifies attribute group, see Section 3.12, "attr_group
(string)".

id
Identifier stored with flagged attributes.

4.4. remove_extra_attrs (group_id, id)

Removes all extra attributes with given id.

group_id
Identifies attribute group, see Section 3.12, "attr_group
(string)".

id
Identifies attributes which should be removed.

4.5. lock_extra_attrs (group_id, id)

Locks extra attributes. Currently locks whole attribute group (not
only id).

group_id
Identifies attribute group, see Section 3.12, "attr_group
(string)".

id
Identifies attributes which should be locked.

4.6. unlock_extra_attrs (group_id, id)

Unlocks extra attributes. Currently unlocks whole attribute group (not
only id).

group_id
Identifies attribute group, see Section 3.12, "attr_group
(string)".

id
Identifies attributes which should be unlocked.

5. Example extra attributes usage

debug=3
memdbg=5
server_signature=0
sip_warning=0
check_via=yes;
dns=no;
rev_dns=no;

children=4;
tcp_children=4;
tcp_max_connections=2048;
port=5060

loadmodule "/home/kubartv/SER/lib/ser/modules/sl.so";
#loadmodule "/home/kubartv/SER/lib/ser/modules/maxfwd.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/tm.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/rr.so";
#loadmodule "/home/kubartv/SER/lib/ser/modules/xmlrpc.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/mysql.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/domain.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/uri_db.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/avp.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/avp_db.so";

loadmodule "/home/kubartv/SER/lib/ser/modules/usrloc.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/registrar.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/xprint.so";
loadmodule "/home/kubartv/SER/lib/ser/modules/eval.so";

loadmodule "/home/kubartv/SER/lib/ser/modules/gflags.so"

#modparam("maxfwd", "max_limit", 70);

modparam("usrloc", "db_mode", 1);
modparam("usrloc|avp_db", "db_url", "mysql://ser:[email protected]/ser")

modparam("avp_db", "attr_group", "id=dlg,flag=dialog_flag,table=dlg_attrs,key_c
olumn=dlg_id");

modparam("gflags", "load_global_attrs", 1);

avpflags dialog_flag;

route["create_dialog"] {
# sets attributes needed by dialog (stored when processing reply)
$dlg_caller = @contact;
$dlg_caller_cseq = @cseq.num;
$dlg_status = "new";
$dlg_init_method = @cseq.method;
$dir = "caller2callee";

t_on_reply("dialog_creation_reply");
return 1;
}

onreply_route["dialog_creation_reply"] {
xplog("L_ERR", "dialog creation reply (%rs, %@cseq.method) [%@from.tag,
%@to.tag]\n");

$res = @msg.response.code;
xplog("L_ERR", " ... response: %$res\n");
if (([email protected]) || (@to.tag=="")) {
# don't create dialog from response without to tag
break;
}
if ($res < 101) {
xplog("L_ERR", " ... I won't create dialog from 100 response.\n
");
break;
}

del_attr("$id"); # xlset_attr works strange when the attribute already
exists
xlset_attr("$id", "call-id:%@call_id caller_tag:%@from.tag callee_tag:%
@to.tag");
if ($res > 299) {
xplog("L_ERR", " ... dialog terminated\n");
remove_extra_attrs("dlg", "$id");
break;
}

xplog("L_ERR", " ... creating dialog '%$id'\n");
# generate dialog id

lock_extra_attrs("dlg", "$id");

# TODO: try to load the dialog (early dialog may exist)?

# update dialog data

if (($dlg_status == "new") && ($res < 200)) {
# early response may arrive after final one
$dlg_callee = @contact;
$dlg_status = "early";
xplog("L_ERR", " ... creating early dialog\n");
}
if ($res >= 200) {
$dlg_callee = @contact;
$dlg_status = "confirmed";
$dlg_confirmed_at = @sys.now.local;
xplog("L_ERR", " ... confirming dialog\n");
}

route("save_dialog");
}

route["save_dialog"] {
if ($dlg_status == "destroyed") {
xplog("L_ERR", " ... destroying dialog %$id\n");

# use this if you want to delete destroyed dialogs:
# remove_extra_attrs("dlg", "$id");

# else if you want leave them in DB (with the time of terminati
on)
$dlg_destroyed_at = @sys.now.local;

# set flag for attributes with name beggining with dlg_
setavpflag("$f./^dlg_/", "dialog_flag");
save_extra_attrs("dlg", "$id");
}
else {
# set flag for attributes with name beggining with dlg_
setavpflag("$f./^dlg_/", "dialog_flag");

save_extra_attrs("dlg", "$id");
}
unlock_extra_attrs("dlg", "$id");
}

route["load_dialog_data"] {
lock_extra_attrs("dlg", "$id");

del_attr("$dlg_init_method"); # used as flag of succesful read of data

# delete all used dlg attrs (because load_extra_attrs doesn't delete th
em itself before adding)
del_attr("$dlg_init_method");
del_attr("$dlg_caller");
del_attr("$dlg_callee");
del_attr("$dlg_caller_cseq");
del_attr("$dlg_callee_cseq");
del_attr("$dlg_status");

load_extra_attrs("dlg", "$id");
if (!$dlg_init_method) {
# dialog was not loaded
unlock_extra_attrs("dlg", "$id");
return -1;
}
return 1;
}

route["load_dialog"] {
# tries to load dialog according tags and callid

# try to load dialog
del_attr("$id"); # xlset_attr works strange when the attribute already
exists
xlset_attr("$id", "call-id:%@call_id caller_tag:%@from.tag callee_tag:%
@to.tag");
if (route("load_dialog_data")) {
$dir = "caller2callee";
return 1;
}

# try to load dialog in other direction
del_attr("$id"); # xlset_attr works strange when the attribute already
exists
xlset_attr("$id", "call-id:%@call_id caller_tag:%@to.tag callee_tag:%@f
rom.tag");
if (route("load_dialog_data")) {
$dir = "callee2caller";
return 1;
}

$id = "error";

return -1;
}

route["update_dialog_reply"] {
if ((@cseq.method == "INVITE") || (@cseq.method == "UPDATE")) {
# target refresh for INVITE dialogs

if ($dir == "caller2calle") { # if request from caller
$dlg_callee = @contact; # update callee's contact (resp
onse!)
}
else {
$dlg_caller = @contact;
}
}
if (@cseq.method=="BYE") {
$dlg_status = "destroyed"; # will be removed in save_dialog
}
}

route["update_dialog"] {
if ((@cseq.method == "INVITE") || (@cseq.method == "UPDATE")) {
# target refresh for INVITE dialogs

if ($dir == "caller2calle") { # if request from caller
$dlg_caller = @contact; # update caller's contact (requ
est!)
}
else {
$dlg_callee = @contact;
}
}

if ($dir == "caller2callee") { # if request from caller
# TODO: verify CSeq before modifying and return 500 if lower th
an last one
$dlg_caller_cseq = @cseq.num;
}
else {
# TODO: verify CSeq before modifying and return 500 if lower th
an last one
$dlg_callee_cseq = @cseq.num;
}

if (method=="BYE") {
$dlg_status = "pre-destroyed"; # to see that BYE already went t
hrough
}
return 1;
}

route["trace_dialog"] {
xplog("L_ERR", " ... dialog '%$id'\n");
xplog("L_ERR", " -> initial method: %$dlg_init_method\n");
xplog("L_ERR", " -> request dir: %$dir\n");
xplog("L_ERR", " -> caller: %$dlg_caller\n");
xplog("L_ERR", " -> caller's CSeq: %$dlg_caller_cseq\n");
xplog("L_ERR", " -> callee: %$dlg_callee\n");
xplog("L_ERR", " -> callee's CSeq: %$dlg_callee_cseq\n");
xplog("L_ERR", " -> status: %$dlg_status\n");
return 1;
}

onreply_route["dialog_reply"] {
if ($id) {
xplog("L_ERR", "In-dialog reply (%rs, %@cseq.method) [%@to.tag,
%@from.tag]\n");
if (!route("load_dialog")) {
xplog("L_ERR", "Can't load dialog data\n");
}
else {
route("update_dialog_reply");
route("trace_dialog");
route("save_dialog");
}
}
}

route {
if (method=="SUBSCRIBE") {
# here we support only INVITE/BYE dialogs
sl_reply("400", "Unsupported");
break;
}

if (!lookup_domain("$td", "@to.uri.host")) {
sl_send_reply("404", "Domain Not Found");
break;
}

if (!lookup_user("To")) {
sl_send_reply("404", "Unknown user");
break;
}

if (method=="REGISTER") {
save("location");
break;
};

xplog("L_ERR", "----> processing request %@cseq.method\n");

if (!lookup_domain("$fd", "@from.uri.host")) {
sl_send_reply("404", "From domain Not Found");
break;
}

if (!lookup_user("From")) {
sl_send_reply("404", "Unknown user in From");
break;
}

if (method != "REGISTER") record_route();

# dialog needs transactions
if (!t_newtran()) {
sl_send_reply("500", "Can not start transaction");
drop;
}

# dialog creation/loading
if ([email protected] || (@to.tag == "")) {
# initial request or non-dialog message
if (method=="INVITE") {
route("create_dialog");
# we don't save the dialog here because AVPs will be se
t
# when reply comes and the dialog will be stored then
}
else {
xplog("L_ERR", "Non-dialog message: %@cseq\n");
}
}
else {
# message within dialog
if (route("load_dialog")) {
route("update_dialog");
route("trace_dialog");
route("save_dialog");
t_on_reply("dialog_reply");
}
else {
xplog("L_ERR", "Message within unknown dialog: %@cseq,
to_tag=%@to.tag from_tag=%@from.tag\n");
}
}

if (loose_route()) {
route(1);
break;
}

if (!lookup("location")) {
t_reply("404", "Not Found");
break;
};
route(1);
}

route[1]
{
xplog("L_ERR", "<---- request %@cseq.method processed\n");
# send it out now; use stateful forwarding as it works reliably
# even for UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}