Skip to content

Commit

Permalink
presence : add min_expires_action parameter
Browse files Browse the repository at this point in the history
action to take when min_expires > 0

possible values are
1 - RC compliant, return "423 Interval Too Brief"
2 - force min_expires in the subscription
  • Loading branch information
lazedo committed Feb 11, 2015
1 parent bba3e53 commit 265a38a
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 19 deletions.
57 changes: 56 additions & 1 deletion modules/presence/doc/presence_admin.xml
Expand Up @@ -322,7 +322,7 @@ modparam("presence", "expires_offset", 10)
<section>
<title><varname>max_expires</varname> (int)</title>
<para>
The the maximum admissible expires value for PUBLISH/SUBSCRIBE
The maximum admissible expires value for PUBLISH/SUBSCRIBE
message (in seconds).
</para>
<para>
Expand All @@ -339,6 +339,61 @@ modparam("presence", "max_expires", 3600)
</example>
</section>

<section>
<title><varname>min_expires</varname> (int)</title>
<para>
The minimum admissible expires value for PUBLISH/SUBSCRIBE
message (in seconds).
</para>
<para>
If &gt; 0 then min_expires_action parameter determines the response.
</para>
<para>
<emphasis>Default value is <quote>0</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>min_expires</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("presence", "min_expires", 1800)
...
</programlisting>
</example>
</section>

<section>
<title><varname>min_expires_action</varname> (int)</title>
<para>
The action to take when UA sends a expires value less then min_expires.
</para>
<para>
<itemizedlist>
<title>Possible Values</title>
<listitem>
<para> 1 : RFC Compliant, returns <quote>423 Interval Too Brief</quote></para>
</listitem>
<listitem>
<para> 2 : forces the min_expires value in the subscription</para>
</listitem>
</itemizedlist>
</para>
<para>
If &gt; 0 then min_expires_action parameter determines the response.
</para>
<para>
<emphasis>Default value is <quote>1</quote>.</emphasis>
</para>
<example>
<title>Set <varname>min_expires</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("presence", "min_expires", 1800)
...
</programlisting>
</example>
</section>

<section>
<title><varname>server_address</varname> (str)</title>
<para>
Expand Down
7 changes: 7 additions & 0 deletions modules/presence/presence.c
Expand Up @@ -140,6 +140,7 @@ 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;
Expand Down Expand Up @@ -197,6 +198,7 @@ static param_export_t params[]={
{ "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},
Expand Down Expand Up @@ -282,6 +284,11 @@ static int mod_init(void)
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");

Expand Down
1 change: 1 addition & 0 deletions modules/presence/presence.h
Expand Up @@ -77,6 +77,7 @@ 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;
Expand Down
37 changes: 29 additions & 8 deletions modules/presence/subscribe.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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, min_expires, 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)
Expand Down Expand Up @@ -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 miexp,
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)
str watcher_user, str watcher_domain,
int* reply_code, str* reply_str)
{
str rec_route= {0, 0};
int rt = 0;
Expand Down Expand Up @@ -1119,8 +1120,19 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int miexp,
}
if(lexpire > mexp)
lexpire = mexp;
if (lexpire && miexp && lexpire < miexp)
lexpire = miexp;

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)
Expand Down Expand Up @@ -1326,6 +1338,15 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int miexp,
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)
Expand Down
9 changes: 6 additions & 3 deletions modules/presence/subscribe.h
Expand Up @@ -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(subs_t* subs,struct sip_msg* msg, int min_expire, int max_expire,
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 min_expire, 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
33 changes: 26 additions & 7 deletions modules/presence/utils_func.c
Expand Up @@ -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: ");
Expand Down Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions modules/presence/utils_func.h
Expand Up @@ -47,6 +47,7 @@

#define LCONTACT_BUF_SIZE 1024
#define BAD_EVENT_CODE 489
#define INTERVAL_TOO_BRIEF 423


#define EVENT_DIALOG_SLA(ev) \
Expand Down

0 comments on commit 265a38a

Please sign in to comment.