Browse code

Merge pull request #78 from kamailio/lazedo/presence

presence : add min_expires param

lazedo authored on 12/02/2015 23:21:27
Showing 7 changed files
... ...
@@ -322,7 +322,7 @@ modparam("presence", "expires_offset", 10)
322 322
        <section>
323 323
                <title><varname>max_expires</varname> (int)</title>
324 324
                <para>
325
-               The the maximum admissible expires value for PUBLISH/SUBSCRIBE
325
+               The maximum admissible expires value for PUBLISH/SUBSCRIBE
326 326
                message (in seconds).
327 327
                </para>
328 328
                <para>
... ...
@@ -340,6 +340,61 @@ modparam("presence", "max_expires", 3600)
340 340
 </section>
341 341
 
342 342
 <section>
343
+    <title><varname>min_expires</varname> (int)</title>
344
+    <para>
345
+        The minimum admissible expires value for PUBLISH/SUBSCRIBE
346
+        message (in seconds).
347
+    </para>
348
+    <para>
349
+        If &gt; 0 then min_expires_action parameter determines the response.
350
+    </para>
351
+    <para>
352
+        <emphasis>Default value is <quote>0</quote>.
353
+        </emphasis>
354
+    </para>
355
+    <example>
356
+        <title>Set <varname>min_expires</varname> parameter</title>
357
+        <programlisting format="linespecific">
358
+            ...
359
+            modparam("presence", "min_expires", 1800)
360
+            ...
361
+        </programlisting>
362
+    </example>
363
+</section>
364
+
365
+<section>
366
+    <title><varname>min_expires_action</varname> (int)</title>
367
+    <para>
368
+        The action to take when UA sends a expires value less then min_expires.
369
+    </para>
370
+    <para>
371
+        <itemizedlist>
372
+            <title>Possible Values</title>
373
+            <listitem>
374
+                <para> 1 : RFC Compliant, returns <quote>423 Interval Too Brief</quote></para>
375
+            </listitem>
376
+            <listitem>
377
+                <para> 2 : forces the min_expires value in the subscription</para>
378
+            </listitem>
379
+        </itemizedlist>
380
+    </para>
381
+    <para>
382
+        If &gt; 0 then min_expires_action parameter determines the response.
383
+    </para>
384
+    <para>
385
+        <emphasis>Default value is <quote>1</quote>.</emphasis>
386
+    </para>
387
+    <example>
388
+        <title>Set <varname>min_expires</varname> parameter</title>
389
+        <programlisting format="linespecific">
390
+            ...
391
+            modparam("presence", "min_expires", 1800)
392
+            ...
393
+        </programlisting>
394
+    </example>
395
+</section>
396
+
397
+<section>
343 398
 		<title><varname>server_address</varname> (str)</title>
344 399
 		<para>
345 400
 		The presence server address which will become the value of Contact header filed 
... ...
@@ -139,6 +139,8 @@ char prefix='a';
139 139
 int startup_time=0;
140 140
 str db_url = {0, 0};
141 141
 int expires_offset = 0;
142
+int min_expires= 0;
143
+int min_expires_action= 1;
142 144
 int max_expires= 3600;
143 145
 int shtable_size= 9;
144 146
 shtable_t subs_htable= NULL;
... ...
@@ -195,6 +197,8 @@ static param_export_t params[]={
195 195
 	{ "to_tag_pref",            PARAM_STRING, &to_tag_pref },
196 196
 	{ "expires_offset",         INT_PARAM, &expires_offset },
197 197
 	{ "max_expires",            INT_PARAM, &max_expires },
198
+	{ "min_expires",            INT_PARAM, &min_expires },
199
+    { "min_expires_action",     INT_PARAM, &min_expires_action },
198 200
 	{ "server_address",         PARAM_STR, &server_address},
199 201
 	{ "subs_htable_size",       INT_PARAM, &shtable_size},
200 202
 	{ "pres_htable_size",       INT_PARAM, &phtable_size},
... ...
@@ -274,6 +278,17 @@ static int mod_init(void)
274 274
 	if(max_expires<= 0)
275 275
 		max_expires = 3600;
276 276
 
277
+	if(min_expires < 0)
278
+		min_expires = 0;
279
+
280
+	if(min_expires > max_expires)
281
+		min_expires = max_expires;
282
+
283
+    if(min_expires_action < 1 || min_expires_action > 2) {
284
+        LM_ERR("min_expires_action must be 1 = RFC 6665/3261 Reply 423, 2 = force min_expires value\n");
285
+        return -1;
286
+    }
287
+    
277 288
 	if(server_address.s== NULL)
278 289
 		LM_DBG("server_address parameter not set in configuration file\n");
279 290
 
... ...
@@ -76,6 +76,8 @@ extern int startup_time;
76 76
 extern char *to_tag_pref;
77 77
 extern int expires_offset;
78 78
 extern str server_address;
79
+extern int min_expires;
80
+extern int min_expires_action;
79 81
 extern int max_expires;
80 82
 extern int subs_dbmode;
81 83
 extern int publ_cache_enabled;
... ...
@@ -58,6 +58,7 @@ static str pu_481_rpl  = str_init("Subscription does not exist");
58 58
 static str pu_400_rpl  = str_init("Bad request");
59 59
 static str pu_500_rpl  = str_init("Server Internal Error");
60 60
 static str pu_489_rpl  = str_init("Bad Event");
61
+static str pu_423_rpl  = str_init("Interval Too Brief");
61 62
 
62 63
 int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire,
63 64
 		str* local_contact)
... ...
@@ -863,11 +864,10 @@ int handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_domain)
863 863
 		ev_param= ev_param->next;
864 864
 	}
865 865
 	
866
-	if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen,
867
-				server_address, watcher_user, watcher_domain)< 0)
866
+	if(extract_sdialog_info_ex(&subs, msg, min_expires, max_expires, &to_tag_gen,
867
+				server_address, watcher_user, watcher_domain, &reply_code, &reply_str)< 0)
868 868
 	{
869
-		LM_ERR("failed to extract dialog information\n");
870
-		goto error;
869
+            goto error;
871 870
 	}
872 871
 
873 872
 	if (pres_notifier_processes > 0 && pa_dbf.start_transaction)
... ...
@@ -1088,9 +1088,10 @@ error:
1088 1088
 }
1089 1089
 
1090 1090
 
1091
-int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
1092
-		int* to_tag_gen, str scontact, str watcher_user,
1093
-		str watcher_domain)
1091
+int extract_sdialog_info_ex(subs_t* subs,struct sip_msg* msg, int miexp,
1092
+		int mexp, int* to_tag_gen, str scontact,
1093
+		str watcher_user, str watcher_domain,
1094
+        int* reply_code, str* reply_str)
1094 1095
 {
1095 1096
 	str rec_route= {0, 0};
1096 1097
 	int rt  = 0;
... ...
@@ -1120,6 +1121,18 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
1120 1120
 	if(lexpire > mexp)
1121 1121
 		lexpire = mexp;
1122 1122
 
1123
+    if (lexpire && miexp && lexpire < miexp) {
1124
+        if(min_expires_action == 1) {
1125
+            LM_DBG("subscription expiration invalid , requested=%d, minimum=%d, returning error \"423 Interval Too brief\"\n", lexpire, miexp);
1126
+            *reply_code = INTERVAL_TOO_BRIEF;
1127
+            *reply_str = pu_423_rpl;
1128
+            goto error;
1129
+        } else {
1130
+            LM_DBG("subscription expiration set to minimum (%d) for requested (%d)\n", lexpire, miexp);
1131
+            lexpire = miexp;
1132
+        }
1133
+    }
1134
+    
1123 1135
 	subs->expires = lexpire;
1124 1136
 
1125 1137
 	if( msg->to==NULL || msg->to->body.s==NULL)
... ...
@@ -1325,6 +1338,15 @@ error:
1325 1325
 	return -1;
1326 1326
 }
1327 1327
 
1328
+int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
1329
+                         int* to_tag_gen, str scontact,
1330
+                         str watcher_user, str watcher_domain)
1331
+{
1332
+    int reply_code = 500;
1333
+    str reply_str = pu_500_rpl;
1334
+    return extract_sdialog_info_ex(subs, msg, min_expires, mexp, to_tag_gen,
1335
+        scontact, watcher_user, watcher_domain, &reply_code, &reply_str);
1336
+}
1328 1337
 
1329 1338
 int get_stored_info(struct sip_msg* msg, subs_t* subs, int* reply_code,
1330 1339
 		str* reply_str)
... ...
@@ -113,11 +113,14 @@ void update_db_subs_timer(db1_con_t *db,db_func_t dbf, shtable_t hash_table,
113 113
 typedef void (*update_db_subs_t)(db1_con_t * ,db_func_t ,shtable_t ,int ,int ,
114 114
 		handle_expired_func_t);
115 115
 
116
+int extract_sdialog_info_ex(subs_t* subs,struct sip_msg* msg, int min_expire,
117
+        int max_expire, int* to_tag_gen, str scontact, str watcher_user,
118
+        str watcher_domain, int* reply_code,str* reply_txt);
116 119
 int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int max_expire,
117 120
 		int* to_tag_gen, str scontact, str watcher_user, str watcher_domain);
118 121
 typedef int (*extract_sdialog_info_t)(subs_t* subs, struct sip_msg* msg,
119
-		int max_expire, int* to_tag_gen, str scontact, str watcher_user,
120
-		str watcher_domain);
122
+        int max_expire, int* to_tag_gen, str scontact, str watcher_user,
123
+        str watcher_domain);
121 124
 void delete_subs(str* pres_uri, str* ev_name, str* to_tag, str* from_tag, str* callid);
122 125
 
123 126
 #endif
... ...
@@ -102,13 +102,13 @@ int a_to_i (char *s,int len)
102 102
 
103 103
 int send_error_reply(struct sip_msg* msg, int reply_code, str reply_str)
104 104
 {
105
-	if(reply_code== BAD_EVENT_CODE)
106
-	{
107
-		str hdr_append;
108
-		char buffer[256];
109
-		int i;
110
-		pres_ev_t* ev= EvList->events;
105
+    str hdr_append;
106
+    char buffer[256];
107
+    int i;
108
+    pres_ev_t* ev= EvList->events;
111 109
 
110
+    if(reply_code== BAD_EVENT_CODE)
111
+	{
112 112
 		hdr_append.s = buffer;
113 113
 		hdr_append.s[0]='\0';
114 114
 		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)
138 138
 			LM_ERR("unable to add lump_rl\n");
139 139
 			return -1;
140 140
 		}
141
-	}
141
+    } else if(reply_code== INTERVAL_TOO_BRIEF) {
142
+        
143
+        hdr_append.s = buffer;
144
+        hdr_append.s[0]='\0';
145
+        hdr_append.len = sprintf(hdr_append.s, "Min-Expires: %d", min_expires);
146
+        if(hdr_append.len < 0)
147
+        {
148
+            LM_ERR("unsuccessful sprintf\n");
149
+            return -1;
150
+        }
151
+        memcpy(hdr_append.s+ hdr_append.len, CRLF, CRLF_LEN);
152
+        hdr_append.len+=  CRLF_LEN;
153
+        hdr_append.s[hdr_append.len]= '\0';
154
+        
155
+        if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
156
+        {
157
+            LM_ERR("unable to add lump_rl\n");
158
+            return -1;
159
+        }
160
+    }
142 161
 
143 162
 	if (slb.freply(msg, reply_code, &reply_str) < 0)
144 163
 	{
... ...
@@ -47,6 +47,7 @@
47 47
 
48 48
 #define LCONTACT_BUF_SIZE 1024
49 49
 #define BAD_EVENT_CODE 489
50
+#define INTERVAL_TOO_BRIEF 423
50 51
 
51 52
 
52 53
 #define EVENT_DIALOG_SLA(ev) \