| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707 |
- UID AVP DB Module
- Jiri Kuthan
- FhG FOKUS
- <[email protected]>
- 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();
- };
- }
|