diff --git a/modules/presence/doc/presence_admin.xml b/modules/presence/doc/presence_admin.xml index f7472f9ee4d..e977699772a 100644 --- a/modules/presence/doc/presence_admin.xml +++ b/modules/presence/doc/presence_admin.xml @@ -322,7 +322,7 @@ modparam("presence", "expires_offset", 10)
<varname>max_expires</varname> (int) - The the maximum admissible expires value for PUBLISH/SUBSCRIBE + The maximum admissible expires value for PUBLISH/SUBSCRIBE message (in seconds). @@ -339,6 +339,61 @@ modparam("presence", "max_expires", 3600)
+
+ <varname>min_expires</varname> (int) + + The minimum admissible expires value for PUBLISH/SUBSCRIBE + message (in seconds). + + + If > 0 then min_expires_action parameter determines the response. + + + Default value is 0. + + + + Set <varname>min_expires</varname> parameter + + ... + modparam("presence", "min_expires", 1800) + ... + + +
+ +
+ <varname>min_expires_action</varname> (int) + + The action to take when UA sends a expires value less then min_expires. + + + + Possible Values + + 1 : RFC Compliant, returns 423 Interval Too Brief + + + 2 : forces the min_expires value in the subscription + + + + + If > 0 then min_expires_action parameter determines the response. + + + Default value is 1. + + + Set <varname>min_expires</varname> parameter + + ... + modparam("presence", "min_expires", 1800) + ... + + +
+
<varname>server_address</varname> (str) diff --git a/modules/presence/presence.c b/modules/presence/presence.c index 517566509b9..1a5284949d5 100644 --- a/modules/presence/presence.c +++ b/modules/presence/presence.c @@ -139,6 +139,8 @@ char prefix='a'; int startup_time=0; str db_url = {0, 0}; int expires_offset = 0; +int min_expires= 0; +int min_expires_action= 1; int max_expires= 3600; int shtable_size= 9; shtable_t subs_htable= NULL; @@ -195,6 +197,8 @@ static param_export_t params[]={ { "to_tag_pref", PARAM_STRING, &to_tag_pref }, { "expires_offset", INT_PARAM, &expires_offset }, { "max_expires", INT_PARAM, &max_expires }, + { "min_expires", INT_PARAM, &min_expires }, + { "min_expires_action", INT_PARAM, &min_expires_action }, { "server_address", PARAM_STR, &server_address}, { "subs_htable_size", INT_PARAM, &shtable_size}, { "pres_htable_size", INT_PARAM, &phtable_size}, @@ -274,6 +278,17 @@ static int mod_init(void) if(max_expires<= 0) max_expires = 3600; + if(min_expires < 0) + min_expires = 0; + + if(min_expires > max_expires) + min_expires = max_expires; + + if(min_expires_action < 1 || min_expires_action > 2) { + LM_ERR("min_expires_action must be 1 = RFC 6665/3261 Reply 423, 2 = force min_expires value\n"); + return -1; + } + if(server_address.s== NULL) LM_DBG("server_address parameter not set in configuration file\n"); diff --git a/modules/presence/presence.h b/modules/presence/presence.h index c1bd288a79d..b725bad5779 100644 --- a/modules/presence/presence.h +++ b/modules/presence/presence.h @@ -76,6 +76,8 @@ extern int startup_time; extern char *to_tag_pref; extern int expires_offset; extern str server_address; +extern int min_expires; +extern int min_expires_action; extern int max_expires; extern int subs_dbmode; extern int publ_cache_enabled; diff --git a/modules/presence/subscribe.c b/modules/presence/subscribe.c index 334dc323d87..48938fce725 100644 --- a/modules/presence/subscribe.c +++ b/modules/presence/subscribe.c @@ -58,6 +58,7 @@ static str pu_481_rpl = str_init("Subscription does not exist"); static str pu_400_rpl = str_init("Bad request"); static str pu_500_rpl = str_init("Server Internal Error"); static str pu_489_rpl = str_init("Bad Event"); +static str pu_423_rpl = str_init("Interval Too Brief"); int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire, str* local_contact) @@ -863,11 +864,10 @@ int handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_domain) ev_param= ev_param->next; } - if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen, - server_address, watcher_user, watcher_domain)< 0) + if(extract_sdialog_info_ex(&subs, msg, min_expires, max_expires, &to_tag_gen, + server_address, watcher_user, watcher_domain, &reply_code, &reply_str)< 0) { - LM_ERR("failed to extract dialog information\n"); - goto error; + goto error; } if (pres_notifier_processes > 0 && pa_dbf.start_transaction) @@ -1088,9 +1088,10 @@ int handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_domain) } -int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, - int* to_tag_gen, str scontact, str watcher_user, - str watcher_domain) +int extract_sdialog_info_ex(subs_t* subs,struct sip_msg* msg, int miexp, + int mexp, int* to_tag_gen, str scontact, + str watcher_user, str watcher_domain, + int* reply_code, str* reply_str) { str rec_route= {0, 0}; int rt = 0; @@ -1120,6 +1121,18 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, if(lexpire > mexp) lexpire = mexp; + if (lexpire && miexp && lexpire < miexp) { + if(min_expires_action == 1) { + LM_DBG("subscription expiration invalid , requested=%d, minimum=%d, returning error \"423 Interval Too brief\"\n", lexpire, miexp); + *reply_code = INTERVAL_TOO_BRIEF; + *reply_str = pu_423_rpl; + goto error; + } else { + LM_DBG("subscription expiration set to minimum (%d) for requested (%d)\n", lexpire, miexp); + lexpire = miexp; + } + } + subs->expires = lexpire; if( msg->to==NULL || msg->to->body.s==NULL) @@ -1325,6 +1338,15 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, return -1; } +int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp, + int* to_tag_gen, str scontact, + str watcher_user, str watcher_domain) +{ + int reply_code = 500; + str reply_str = pu_500_rpl; + return extract_sdialog_info_ex(subs, msg, min_expires, mexp, to_tag_gen, + scontact, watcher_user, watcher_domain, &reply_code, &reply_str); +} int get_stored_info(struct sip_msg* msg, subs_t* subs, int* reply_code, str* reply_str) diff --git a/modules/presence/subscribe.h b/modules/presence/subscribe.h index 00c02a3a0cd..776d8dadd89 100644 --- a/modules/presence/subscribe.h +++ b/modules/presence/subscribe.h @@ -113,11 +113,14 @@ void update_db_subs_timer(db1_con_t *db,db_func_t dbf, shtable_t hash_table, typedef void (*update_db_subs_t)(db1_con_t * ,db_func_t ,shtable_t ,int ,int , handle_expired_func_t); +int extract_sdialog_info_ex(subs_t* subs,struct sip_msg* msg, int min_expire, + int max_expire, int* to_tag_gen, str scontact, str watcher_user, + str watcher_domain, int* reply_code,str* reply_txt); int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int max_expire, int* to_tag_gen, str scontact, str watcher_user, str watcher_domain); typedef int (*extract_sdialog_info_t)(subs_t* subs, struct sip_msg* msg, - int max_expire, int* to_tag_gen, str scontact, str watcher_user, - str watcher_domain); + int max_expire, int* to_tag_gen, str scontact, str watcher_user, + str watcher_domain); void delete_subs(str* pres_uri, str* ev_name, str* to_tag, str* from_tag, str* callid); #endif diff --git a/modules/presence/utils_func.c b/modules/presence/utils_func.c index e7dbd06be20..64d0527ccb2 100644 --- a/modules/presence/utils_func.c +++ b/modules/presence/utils_func.c @@ -102,13 +102,13 @@ int a_to_i (char *s,int len) int send_error_reply(struct sip_msg* msg, int reply_code, str reply_str) { - if(reply_code== BAD_EVENT_CODE) - { - str hdr_append; - char buffer[256]; - int i; - pres_ev_t* ev= EvList->events; + str hdr_append; + char buffer[256]; + int i; + pres_ev_t* ev= EvList->events; + if(reply_code== BAD_EVENT_CODE) + { hdr_append.s = buffer; hdr_append.s[0]='\0'; hdr_append.len = sprintf(hdr_append.s, "Allow-Events: "); @@ -138,7 +138,26 @@ int send_error_reply(struct sip_msg* msg, int reply_code, str reply_str) LM_ERR("unable to add lump_rl\n"); return -1; } - } + } else if(reply_code== INTERVAL_TOO_BRIEF) { + + hdr_append.s = buffer; + hdr_append.s[0]='\0'; + hdr_append.len = sprintf(hdr_append.s, "Min-Expires: %d", min_expires); + if(hdr_append.len < 0) + { + LM_ERR("unsuccessful sprintf\n"); + return -1; + } + memcpy(hdr_append.s+ hdr_append.len, CRLF, CRLF_LEN); + hdr_append.len+= CRLF_LEN; + hdr_append.s[hdr_append.len]= '\0'; + + if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 ) + { + LM_ERR("unable to add lump_rl\n"); + return -1; + } + } if (slb.freply(msg, reply_code, &reply_str) < 0) { diff --git a/modules/presence/utils_func.h b/modules/presence/utils_func.h index bb3a1810ebc..cf7c030b7b6 100644 --- a/modules/presence/utils_func.h +++ b/modules/presence/utils_func.h @@ -47,6 +47,7 @@ #define LCONTACT_BUF_SIZE 1024 #define BAD_EVENT_CODE 489 +#define INTERVAL_TOO_BRIEF 423 #define EVENT_DIALOG_SLA(ev) \