From 16038cd0219f1c87910257a266423d889eef0721 Mon Sep 17 00:00:00 2001 From: Andrei Datcu Date: Mon, 4 Aug 2014 13:49:43 +0300 Subject: [PATCH] [usrloc]New contact-aware events --- modules/usrloc/README | 49 ++++++++ modules/usrloc/doc/usrloc_admin.xml | 177 ++++++++++++++++++++-------- modules/usrloc/ucontact.c | 6 + modules/usrloc/udomain.c | 98 ++++++++++++++- modules/usrloc/udomain.h | 2 + modules/usrloc/urecord.c | 8 ++ 6 files changed, 292 insertions(+), 48 deletions(-) diff --git a/modules/usrloc/README b/modules/usrloc/README index 8c55dd19adf..d55426f1525 100644 --- a/modules/usrloc/README +++ b/modules/usrloc/README @@ -86,6 +86,9 @@ Bogdan-Andrei Iancu 1.7.1. E_UL_AOR_INSERT 1.7.2. E_UL_AOR_DELETE + 1.7.3. E_UL_CONTACT_INSERT + 1.7.4. E_UL_CONTACT_DELETE + 1.7.5. E_UL_CONTACT_UPDATE 2. Developer Guide @@ -754,6 +757,52 @@ modparam("usrloc", "hash_size", 10) Parameters: * aor - The AOR of the deleted record. +1.7.3. E_UL_CONTACT_INSERT + + This event is raised when a new contact is inserted in any of + the existing AOR's contact list. For each new contact, if its + AOR does not exist in the memory, then both the E_UL_AOR_CREATE + and E_UL_CONTACT_INSERT events will be raised. + + Parameters: + * address - The address of the inserted contact. + * callid - The Call-ID header of the registration message. + * received - IP, port and protocol the registration message + was received from. If these have the same value as the + contact's address (see the address parameter) then the + received parameter will be an empty string. + * cseq - The cseq number as an int value. + +1.7.4. E_UL_CONTACT_DELETE + + This event is raised when a contact is deleted from an existing + AOR's contact list. If the contact is the only one in the list + then both the E_UL_AOR_DELETE and E_UL_CONTACT_DELETE events + will be raised. + + Parameters: + * address - The address of the inserted contact. + * callid - The Call-ID header of the registration message. + * received - IP, port and protocol the registration message + was received from. If these have the same value as the + contact's address (see the address parameter) then the + received parameter will be an empty string. + * cseq - The cseq number as an int value. + +1.7.5. E_UL_CONTACT_UPDATE + + This event is raised when a contact's info is updated by + receiving another registration message. + + Parameters: + * address - The address of the inserted contact. + * callid - The Call-ID header of the registration message. + * received - IP, port and protocol the registration message + was received from. If these have the same value as the + contact's address (see the address parameter) then the + received parameter will be an empty string. + * cseq - The cseq number as an int value. + Chapter 2. Developer Guide 2.1. Available Functions diff --git a/modules/usrloc/doc/usrloc_admin.xml b/modules/usrloc/doc/usrloc_admin.xml index 0dfb85ad4f7..8c7ca585cb6 100644 --- a/modules/usrloc/doc/usrloc_admin.xml +++ b/modules/usrloc/doc/usrloc_admin.xml @@ -1,14 +1,14 @@ - + &adminguide; - +
Overview - User location module. The module keeps a user location table and - provides access to the table to other modules. The module exports no + User location module. The module keeps a user location table and + provides access to the table to other modules. The module exports no functions that could be used directly from scripts.
@@ -16,16 +16,16 @@ How the contacts are matched (for same AOR - Address of Record) is an important aspect of the usrloc modules, especialy in the context of NAT - traversal - this raise mre problems since contacts from different + traversal - this raise mre problems since contacts from different phones of same users may overlap (if behind NATs with same configuration) or the re-register contact of same phone may be seen as a new one (due different binding via NAT). - The SIP RFC 3261 publishes a matching algorithm based only on the + The SIP RFC 3261 publishes a matching algorithm based only on the contact string with callid and cseq number extra checking (if callid is the same, it must have a higher cseq number, otherwise invalid). - But as argumented above, this is not enough in NAT traversal context, + But as argumented above, this is not enough in NAT traversal context, so the &osips; implementation of contact machting offers more algorithms: @@ -42,7 +42,7 @@ contact and callid based - an extension of the first case - the contact and callid must match as strings; the cseq must be higher than the previous one - so be - careful how you deal with REGISTER retransmissions in this + careful how you deal with REGISTER retransmissions in this case. @@ -140,7 +140,7 @@
External Libraries or Applications - The following libraries or applications must be installed before + The following libraries or applications must be installed before running &osips; with this module loaded: @@ -157,8 +157,8 @@
<varname>nat_bflag</varname> (string/integer) - The name of the branch flag to be used as NAT marker (if the contact - is or not natted). This is a branch flag and it will be imported and + The name of the branch flag to be used as NAT marker (if the contact + is or not natted). This is a branch flag and it will be imported and used by all other modules depending of usrloc module. @@ -504,7 +504,7 @@ modparam("usrloc", "attr_column", "attr") <varname>use_domain</varname> (integer) If the domain part of the user should be also saved and used for - identifing the user (along with the username part). Useful in + identifing the user (along with the username part). Useful in multi domain scenarios. Non 0 value means true. @@ -547,8 +547,8 @@ modparam("usrloc", "desc_time_order", 1)
<varname>timer_interval</varname> (integer) - Number of seconds between two timer runs. The module uses timer to - delete expired contacts, synchronize with database and other tasks, + Number of seconds between two timer runs. The module uses timer to + delete expired contacts, synchronize with database and other tasks, that need to be run periodically. @@ -590,60 +590,60 @@ modparam("usrloc", "db_url", "&exampledb;") <varname>db_mode</varname> (integer) The usrloc module can utilize database for persistent contact storage. - If you use database, your contacts will survive machine restarts or - SW crashes. The disadvantage is that accessing database can be very - time consuming. Therefore, usrloc module implements four database + If you use database, your contacts will survive machine restarts or + SW crashes. The disadvantage is that accessing database can be very + time consuming. Therefore, usrloc module implements four database accessing modes: - 0 - This disables database completely. Only memory will be used. - Contacts will not survive restart. Use this value if you need a - really fast usrloc and contact persistence is not necessary or + 0 - This disables database completely. Only memory will be used. + Contacts will not survive restart. Use this value if you need a + really fast usrloc and contact persistence is not necessary or is provided by other means. - 1 - Write-Through scheme. All changes to usrloc are immediately - reflected in database too. This is very slow, but very reliable. - Use this scheme if speed is not your priority but need to make - sure that no registered contacts will be lost during crash or + 1 - Write-Through scheme. All changes to usrloc are immediately + reflected in database too. This is very slow, but very reliable. + Use this scheme if speed is not your priority but need to make + sure that no registered contacts will be lost during crash or reboot. - 2 - Write-Back scheme. This is a combination of previous two - schemes. All changes are made to memory and database - synchronization is done in the timer. The timer deletes all - expired contacts and flushes all modified or new contacts to - database. Use this scheme if you encounter high-load peaks - and want them to process as fast as possible. The mode will - not help at all if the load is high all the time. Also, latency - of this mode is much lower than latency of mode 1, but slightly + 2 - Write-Back scheme. This is a combination of previous two + schemes. All changes are made to memory and database + synchronization is done in the timer. The timer deletes all + expired contacts and flushes all modified or new contacts to + database. Use this scheme if you encounter high-load peaks + and want them to process as fast as possible. The mode will + not help at all if the load is high all the time. Also, latency + of this mode is much lower than latency of mode 1, but slightly higher than latency of mode 0. 3 - DB-Only scheme. No memory cache is kept, all operations being - directly performed with the database. The timer deletes all + directly performed with the database. The timer deletes all expired contacts from database - cleans after clients that didn't un-register or re-register. The mode is useful if you configure more servers sharing the same DB without any replication at SIP level. The mode may be slower due the high number of DB operation. For example NAT pinging is a killer since during each ping cycle - all nated contact are loaded from the DB; The lack of memory + all nated contact are loaded from the DB; The lack of memory caching also disable the statistics exports. - In case of crash or restart contacts that are in memory only and - haven't been flushed yet will get lost. If you want minimize the + In case of crash or restart contacts that are in memory only and + haven't been flushed yet will get lost. If you want minimize the risk, use shorter timer interval. @@ -665,8 +665,8 @@ modparam("usrloc", "db_mode", 2)
<varname>matching_mode</varname> (integer) - What contact matching algorithm to be used. Refer to section - for the description of the + What contact matching algorithm to be used. Refer to section + for the description of the algorithms. @@ -679,7 +679,7 @@ modparam("usrloc", "db_mode", 2) - 1 - CONTACT and CALLID based + 1 - CONTACT and CALLID based matching algorithm. @@ -703,7 +703,7 @@ modparam("usrloc", "matching_mode", 1) <varname>cseq_delay</varname> (integer) Delay (in seconds) for accepting as retransmissions register requests - with same Call-ID and Cseq. The delay is calculated starting from the + with same Call-ID and Cseq. The delay is calculated starting from the receiving time of the first register with that Call-ID and Cseq. @@ -950,11 +950,11 @@ modparam("usrloc", "hash_size", 10) backword compatibility) - flags - internal USRLOC flags of the + flags - internal USRLOC flags of the contact - cflags - per branch flags of the + cflags - per branch flags of the contact @@ -1025,15 +1025,15 @@ modparam("usrloc", "hash_size", 10) users Number of AOR existing in the USRLOC memory cache for that domain - - can not be resetted; this statistic will be register for each + - can not be resetted; this statistic will be register for each used domain (Ex: location).
contacts - Number of contacts existing in the USRLOC memory cache for that - domain - can not be resetted; this statistic will be register for + Number of contacts existing in the USRLOC memory cache for that + domain - can not be resetted; this statistic will be register for each used domain (Ex: location).
@@ -1041,7 +1041,7 @@ modparam("usrloc", "hash_size", 10) expires Total number of expired contacts for that domain - can be resetted; - this statistic will be register for each used domain + this statistic will be register for each used domain (Ex: location).
@@ -1087,5 +1087,90 @@ modparam("usrloc", "hash_size", 10)
+
+ + <function moreinfo="none">E_UL_CONTACT_INSERT</function> + + + This event is raised when a new contact is inserted in any of the + existing AOR's contact list. For each new contact, if its AOR does + not exist in the memory, then both the E_UL_AOR_CREATE and + E_UL_CONTACT_INSERT events will be raised. + + Parameters: + + + address - The address of the inserted contact. + + + callid - The Call-ID header of the registration message. + + + received - IP, port and protocol the registration + message was received from. If these have the same value as the + contact's address (see the address parameter) then the received + parameter will be an empty string. + + + cseq - The cseq number as an int value. + + +
+
+ + <function moreinfo="none">E_UL_CONTACT_DELETE</function> + + + This event is raised when a contact is deleted from an + existing AOR's contact list. If the contact is the only one in + the list then both the E_UL_AOR_DELETE and + E_UL_CONTACT_DELETE events will be raised. + + Parameters: + + + address - The address of the inserted contact. + + + callid - The Call-ID header of the registration message. + + + received - IP, port and protocol the registration + message was received from. If these have the same value as the + contact's address (see the address parameter) then the received + parameter will be an empty string. + + + cseq - The cseq number as an int value. + + +
+
+ + <function moreinfo="none">E_UL_CONTACT_UPDATE</function> + + + This event is raised when a contact's info is updated by receiving + another registration message. + + Parameters: + + + address - The address of the inserted contact. + + + callid - The Call-ID header of the registration message. + + + received - IP, port and protocol the registration + message was received from. If these have the same value as the + contact's address (see the address parameter) then the received + parameter will be an empty string. + + + cseq - The cseq number as an int value. + + +
diff --git a/modules/usrloc/ucontact.c b/modules/usrloc/ucontact.c index 389bae1c754..aa489e7bc69 100644 --- a/modules/usrloc/ucontact.c +++ b/modules/usrloc/ucontact.c @@ -49,6 +49,9 @@ #include "urecord.h" #include "ucontact.h" #include "ureplication.h" +#include "udomain.h" + +extern event_id_t ei_c_update_id; /* * Determines the IP address of the next hop on the way to given contact based @@ -297,6 +300,9 @@ int mem_update_ucontact(ucontact_t* _c, ucontact_info_t* _ci) LM_ERR("failed to resolve next hop. keeping old one - '%.*s'\n", _c->next_hop.name.len, _c->next_hop.name.s); + ul_raise_contact_event(ei_c_update_id, &_c->c, &_c->callid, + &_c->received, _c->cseq); + return 0; } diff --git a/modules/usrloc/udomain.c b/modules/usrloc/udomain.c index 162829bbe00..7a555b3bcc3 100644 --- a/modules/usrloc/udomain.c +++ b/modules/usrloc/udomain.c @@ -123,11 +123,25 @@ int new_udomain(str* _n, int _s, udomain_t** _d) static event_id_t ei_ins_id = EVI_ERROR; static event_id_t ei_del_id = EVI_ERROR; +event_id_t ei_c_ins_id = EVI_ERROR; +event_id_t ei_c_del_id = EVI_ERROR; +event_id_t ei_c_update_id = EVI_ERROR; static str ei_ins_name = str_init("E_UL_AOR_INSERT"); static str ei_del_name = str_init("E_UL_AOR_DELETE"); +static str ei_contact_ins_name = str_init("E_UL_CONTACT_INSERT"); +static str ei_contact_del_name = str_init("E_UL_CONTACT_DELETE"); +static str ei_contact_update_name = str_init("E_UL_CONTACT_UPDATE"); static str ei_aor_name = str_init("aor"); +static str ei_c_addr_name = str_init("address"); +static str ei_c_recv_name = str_init("received"); +static str ei_callid_name = str_init("callid"); +static str ei_cseq_name = str_init("cseq"); static evi_params_p ul_event_params; static evi_param_p ul_aor_param; +static evi_params_p ul_contact_event_params; +static evi_param_p ul_c_addr_param, ul_c_callid_param; +static evi_param_p ul_c_recv_param; +static evi_param_p ul_c_cseq_param; /*! \brief * Initialize event structures @@ -136,13 +150,31 @@ int ul_event_init(void) { ei_ins_id = evi_publish_event(ei_ins_name); if (ei_ins_id == EVI_ERROR) { - LM_ERR("cannot register insert event\n"); + LM_ERR("cannot register aor insert event\n"); return -1; } ei_del_id = evi_publish_event(ei_del_name); if (ei_del_id == EVI_ERROR) { - LM_ERR("cannot register delete event\n"); + LM_ERR("cannot register aor delete event\n"); + return -1; + } + + ei_c_ins_id = evi_publish_event(ei_contact_ins_name); + if (ei_c_ins_id == EVI_ERROR) { + LM_ERR("cannot register contact insert event\n"); + return -1; + } + + ei_c_del_id = evi_publish_event(ei_contact_del_name); + if (ei_c_del_id == EVI_ERROR) { + LM_ERR("cannot register contact delete event\n"); + return -1; + } + + ei_c_update_id = evi_publish_event(ei_contact_update_name); + if (ei_c_update_id == EVI_ERROR) { + LM_ERR("cannot register contact delete event\n"); return -1; } @@ -158,6 +190,37 @@ int ul_event_init(void) return -1; } + ul_contact_event_params = pkg_malloc(sizeof(evi_params_t)); + if (!ul_contact_event_params) { + LM_ERR("no more pkg memory\n"); + return -1; + } + memset(ul_contact_event_params, 0, sizeof(evi_params_t)); + + ul_c_addr_param = evi_param_create(ul_contact_event_params, &ei_c_addr_name); + if (!ul_c_addr_param) { + LM_ERR("cannot create contact address parameter\n"); + return -1; + } + + ul_c_callid_param = evi_param_create(ul_contact_event_params, &ei_callid_name); + if (!ul_c_callid_param) { + LM_ERR("cannot create callid parameter\n"); + return -1; + } + + ul_c_recv_param = evi_param_create(ul_contact_event_params, &ei_c_recv_name); + if (!ul_c_recv_param) { + LM_ERR("cannot create received parameter\n"); + return -1; + } + + ul_c_cseq_param = evi_param_create(ul_contact_event_params, &ei_cseq_name); + if (!ul_c_cseq_param) { + LM_ERR("cannot create cseq parameter\n"); + return -1; + } + return 0; } @@ -178,6 +241,37 @@ static void ul_raise_event(event_id_t _e, struct urecord* _r) LM_ERR("cannot raise event\n"); } +void ul_raise_contact_event(event_id_t _e, str *addr, str *callid, str *recv, + int cseq) +{ + if (_e == EVI_ERROR) { + LM_ERR("event not yet registered %d\n", _e); + return; + } + if (evi_param_set_str(ul_c_addr_param, addr) < 0) { + LM_ERR("cannot set contact address parameter\n"); + return; + } + + if (evi_param_set_str(ul_c_callid_param, callid) < 0) { + LM_ERR("cannot set callid parameter\n"); + return; + } + + if (evi_param_set_str(ul_c_recv_param, recv) < 0) { + LM_ERR("cannot set received parameter\n"); + return; + } + + if (evi_param_set_int(ul_c_cseq_param, &cseq) < 0) { + LM_ERR("cannot set cseq parameter\n"); + return; + } + + if (evi_raise_event(_e, ul_contact_event_params) < 0) + LM_ERR("cannot raise event\n"); +} + /*! \brief * Free all memory allocated for diff --git a/modules/usrloc/udomain.h b/modules/usrloc/udomain.h index dce8236efef..6623c901e56 100644 --- a/modules/usrloc/udomain.h +++ b/modules/usrloc/udomain.h @@ -181,5 +181,7 @@ int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r, +void ul_raise_contact_event(event_id_t _e, str *addr, str *callid, str *recv, + int cseq); #endif /* UDOMAIN_H */ diff --git a/modules/usrloc/urecord.c b/modules/usrloc/urecord.c index 6aef6136094..9e863b52590 100644 --- a/modules/usrloc/urecord.c +++ b/modules/usrloc/urecord.c @@ -45,12 +45,16 @@ #include "utime.h" #include "ul_callback.h" #include "ureplication.h" +#include "udomain.h" int matching_mode = CONTACT_ONLY; int cseq_delay = 20; +extern event_id_t ei_c_ins_id; +extern event_id_t ei_c_del_id; + /*! \brief * Create and initialize new record structure */ @@ -172,6 +176,8 @@ ucontact_t* mem_insert_ucontact(urecord_t* _r, str* _c, ucontact_info_t* _ci) _r->contacts = c; } + ul_raise_contact_event(ei_c_ins_id, &c->c, &c->callid, &c->received, + c->cseq); return c; } @@ -192,6 +198,8 @@ void mem_remove_ucontact(urecord_t* _r, ucontact_t* _c) _c->next->prev = 0; } } + ul_raise_contact_event(ei_c_del_id, &_c->c, &_c->callid, &_c->received, + _c->cseq); }