62693808c8b868500d5bc753eaa9cdddee9b1cc2
[sip-router] / src / modules / dialog / dlg_req_within.c
1 /*
2  * Copyright (C) 2007 Voice System SRL
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20 */
21
22
23 /*!
24  * \file
25  * \brief Requests
26  * \ingroup dialog
27  * Module: \ref dialog
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "../../core/dprint.h"
34 #include "../../core/ut.h"
35 #include "../../lib/srdb1/db.h"
36 #include "../../core/dprint.h"
37 #include "../../core/config.h"
38 #include "../../core/socket_info.h"
39 #include "../../core/dset.h"
40 #include "../../modules/tm/dlg.h"
41 #include "../../modules/tm/tm_load.h"
42 #include "../../core/counters.h"
43 #include "dlg_timer.h"
44 #include "dlg_hash.h"
45 #include "dlg_handlers.h"
46 #include "dlg_req_within.h"
47 #include "dlg_db_handler.h"
48
49
50 #define MAX_FWD_HDR        "Max-Forwards: " MAX_FWD CRLF
51 #define MAX_FWD_HDR_LEN    (sizeof(MAX_FWD_HDR) - 1)
52
53 extern str dlg_extra_hdrs;
54 extern str dlg_lreq_callee_headers;
55 extern int dlg_ka_failed_limit;
56
57 /**
58  *
59  */
60 int free_tm_dlg(dlg_t *td)
61 {
62         if(td)
63         {
64                 if(td->route_set)
65                         free_rr(&td->route_set);
66                 pkg_free(td);
67         }
68         return 0;
69 }
70
71
72
73 dlg_t * build_dlg_t(struct dlg_cell * cell, int dir){
74
75         dlg_t* td = NULL;
76         str cseq;
77         unsigned int loc_seq;
78         char nbuf[MAX_URI_SIZE];
79         char dbuf[80];
80         str nuri = STR_NULL;
81         str duri = STR_NULL;
82         size_t sz;
83         char *p;
84
85         /*remote target--- Request URI*/
86         if(cell->contact[dir].s==0 || cell->contact[dir].len==0){
87                 LM_ERR("no contact available\n");
88                 goto error;
89         }
90         if(cell->route_set[dir].s==NULL || cell->route_set[dir].len<=0){
91                 /*try to restore alias parameter if no route set */
92                 nuri.s = nbuf;
93                 nuri.len = MAX_URI_SIZE;
94                 duri.s = dbuf;
95                 duri.len = 80;
96                 if(uri_restore_rcv_alias(&cell->contact[dir], &nuri, &duri)<0) {
97                         nuri.len = 0;
98                         duri.len = 0;
99                 }
100         }
101         if(nuri.len>0 && duri.len>0) {
102                 sz = sizeof(dlg_t) + (nuri.len+duri.len+2)*sizeof(char);
103         } else {
104                 sz = sizeof(dlg_t);
105         }
106         td = (dlg_t*)pkg_malloc(sz);
107         if(!td){
108                 LM_ERR("out of pkg memory\n");
109                 return NULL;
110         }
111         memset(td, 0, sz);
112
113         /*local sequence number*/
114         cseq = (dir == DLG_CALLER_LEG) ?        cell->cseq[DLG_CALLEE_LEG]:
115                                                                                 cell->cseq[DLG_CALLER_LEG];
116         if(str2int(&cseq, &loc_seq) != 0){
117                 LM_ERR("invalid cseq\n");
118                 goto error;
119         }
120         /*we don not increase here the cseq as this will be done by TM*/
121         td->loc_seq.value = loc_seq;
122         td->loc_seq.is_set = 1;
123
124         /*route set*/
125         if( cell->route_set[dir].s && cell->route_set[dir].len){
126                 if( parse_rr_body(cell->route_set[dir].s, cell->route_set[dir].len,
127                                                 &td->route_set) !=0){
128                         LM_ERR("failed to parse route set\n");
129                         goto error;
130                 }
131         }
132
133         if(nuri.len>0 && duri.len>0) {
134                 /* req uri */
135                 p = (char*)td + sizeof(dlg_t);
136                 strncpy(p, nuri.s, nuri.len);
137                 p[nuri.len] = '\0';
138                 td->rem_target.s = p;
139                 td->rem_target.len = nuri.len;
140                 /* dst uri */
141                 p += nuri.len + 1;
142                 strncpy(p, duri.s, duri.len);
143                 p[duri.len] = '\0';
144                 td->dst_uri.s = p;
145                 td->dst_uri.len = duri.len;
146         } else {
147                 td->rem_target = cell->contact[dir];
148         }
149
150         td->rem_uri     =   (dir == DLG_CALLER_LEG)?    cell->from_uri: cell->to_uri;
151         td->loc_uri     =       (dir == DLG_CALLER_LEG)?        cell->to_uri: cell->from_uri;
152         td->id.call_id = cell->callid;
153         td->id.rem_tag = cell->tag[dir];
154         td->id.loc_tag = (dir == DLG_CALLER_LEG) ?      cell->tag[DLG_CALLEE_LEG]:
155                                                                                                 cell->tag[DLG_CALLER_LEG];
156
157         td->state= DLG_CONFIRMED;
158         td->send_sock = cell->bind_addr[dir];
159
160         return td;
161
162 error:
163         free_tm_dlg(td);
164         return NULL;
165 }
166
167
168
169 /* callback function to handle responses to the BYE request */
170 void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
171
172         struct dlg_cell* dlg;
173         int event, old_state, new_state, unref, ret;
174         dlg_iuid_t *iuid = NULL;
175
176         if(ps->param == NULL || *ps->param == NULL){
177                 LM_ERR("invalid parameter\n");
178                 return;
179         }
180
181         if(ps->code < 200){
182                 LM_DBG("receiving a provisional reply\n");
183                 return;
184         }
185
186         LM_DBG("receiving a final reply %d\n",ps->code);
187
188         iuid = (dlg_iuid_t*)(*ps->param);
189         dlg = dlg_get_by_iuid(iuid);
190         if(dlg==0)
191                 return;
192
193         event = DLG_EVENT_REQBYE;
194         next_state_dlg(dlg, event, &old_state, &new_state, &unref);
195
196         if(new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED){
197
198                 LM_DBG("removing dialog with h_entry %u and h_id %u\n", 
199                         dlg->h_entry, dlg->h_id);
200
201                 /* remove from timer */
202                 ret = remove_dialog_timer(&dlg->tl);
203                 if (ret < 0) {
204                         LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] "
205                                 "with clid '%.*s' and tags '%.*s' '%.*s'\n",
206                                 dlg, dlg->h_entry, dlg->h_id,
207                                 dlg->callid.len, dlg->callid.s,
208                                 dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
209                                 dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
210                 } else if (ret > 0) {
211                         LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
212                                 "with clid '%.*s' and tags '%.*s' '%.*s'\n",
213                                 dlg, dlg->h_entry, dlg->h_id,
214                                 dlg->callid.len, dlg->callid.s,
215                                 dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
216                                 dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
217                 } else {
218                         unref++;
219                 }
220                 /* dialog terminated (BYE) */
221                 run_dlg_callbacks( DLGCB_TERMINATED_CONFIRMED, dlg, ps->req, ps->rpl, DLG_DIR_NONE, 0);
222
223                 LM_DBG("first final reply\n");
224                 /* derefering the dialog */
225                 dlg_unref(dlg, unref+1);
226
227                 if_update_stat( dlg_enable_stats, active_dlgs, -1);
228         }
229
230         if(new_state == DLG_STATE_DELETED && old_state == DLG_STATE_DELETED ) {
231                 /* trash the dialog from DB and memory */
232                 LM_DBG("second final reply\n");
233                 /* delete the dialog from DB */
234                 if (dlg_db_mode)
235                         remove_dialog_from_db(dlg);
236                 /* force delete from mem */
237                 dlg_unref(dlg, 1);
238         }
239         dlg_iuid_sfree(iuid);
240 }
241
242
243 /* callback function to handle responses to the keep-alive request */
244 void dlg_ka_cb_all(struct cell* t, int type, struct tmcb_params* ps, int dir)
245 {
246         int tend;
247         dlg_cell_t* dlg;
248         dlg_iuid_t *iuid = NULL;
249
250         if(ps->param == NULL || *ps->param == NULL) {
251                 LM_ERR("invalid parameter\n");
252                 return;
253         }
254
255         if(ps->code < 200) {
256                 LM_DBG("receiving a provisional reply\n");
257                 return;
258         }
259
260         LM_DBG("receiving a final reply %d\n",ps->code);
261
262         iuid = (dlg_iuid_t*)(*ps->param);
263         dlg = dlg_get_by_iuid(iuid);
264         if(dlg==0) {
265                 dlg_iuid_sfree(iuid);
266                 return;
267         }
268
269         if(ps->code==408 || ps->code==481) {
270                 if (dlg->state != DLG_STATE_CONFIRMED) {
271                         LM_DBG("skip updating non-confirmed dialogs\n");
272                         goto done;
273                 }
274                 tend = 0;
275                 if(dir==DLG_CALLER_LEG) {
276                         dlg->ka_src_counter++;
277                         if(dlg->ka_src_counter>=dlg_ka_failed_limit) {
278                                 tend = 1;
279                         }
280                 } else {
281                         dlg->ka_dst_counter++;
282                         if(dlg->ka_dst_counter>=dlg_ka_failed_limit) {
283                                 tend = 1;
284                         }
285                 }
286                 if(tend) {
287                         if(update_dlg_timer(&dlg->tl, 10)<0) {
288                                 LM_ERR("failed to update dialog lifetime\n");
289                                 goto done;
290                         }
291                         dlg->lifetime = 10;
292                         dlg->dflags |= DLG_FLAG_CHANGED;
293                 }
294         } else {
295                 if (dlg->state == DLG_STATE_CONFIRMED) {
296                         if(dir==DLG_CALLER_LEG) {
297                                 dlg->ka_src_counter = 0;
298                         } else {
299                                 dlg->ka_dst_counter = 0;
300                         }
301                 }
302         }
303
304 done:
305         dlg_unref(dlg, 1);
306         dlg_iuid_sfree(iuid);
307 }
308
309 /* callback function to handle responses to the keep-alive request to src */
310 void dlg_ka_cb_src(struct cell* t, int type, struct tmcb_params* ps)
311 {
312         dlg_ka_cb_all(t, type, ps, DLG_CALLER_LEG);
313 }
314
315 /* callback function to handle responses to the keep-alive request to dst */
316 void dlg_ka_cb_dst(struct cell* t, int type, struct tmcb_params* ps)
317 {
318         dlg_ka_cb_all(t, type, ps, DLG_CALLEE_LEG);
319 }
320
321 static inline int build_extra_hdr(struct dlg_cell * cell, str *extra_hdrs,
322                 str *str_hdr)
323 {
324         char *p;
325         int blen;
326
327         str_hdr->len = MAX_FWD_HDR_LEN + dlg_extra_hdrs.len;
328         if(extra_hdrs && extra_hdrs->len>0)
329                 str_hdr->len += extra_hdrs->len;
330
331         blen = str_hdr->len + 3 /* '\r\n\0' */;
332
333         /* reserve space for callee headers in local requests */
334         if(dlg_lreq_callee_headers.len>0)
335                 blen += dlg_lreq_callee_headers.len + 2 /* '\r\n' */;
336
337         str_hdr->s = (char*)pkg_malloc( blen * sizeof(char) );
338         if(!str_hdr->s){
339                 LM_ERR("out of pkg memory\n");
340                 goto error;
341         }
342
343         memcpy(str_hdr->s , MAX_FWD_HDR, MAX_FWD_HDR_LEN );
344         p = str_hdr->s + MAX_FWD_HDR_LEN;
345         if (dlg_extra_hdrs.len) {
346                 memcpy( p, dlg_extra_hdrs.s, dlg_extra_hdrs.len);
347                 p += dlg_extra_hdrs.len;
348         }
349         if (extra_hdrs && extra_hdrs->len>0)
350                 memcpy( p, extra_hdrs->s, extra_hdrs->len);
351
352         return 0;
353
354 error: 
355         return -1;
356 }
357
358
359
360 /* cell- pointer to a struct dlg_cell
361  * dir- direction: the request will be sent to:
362  *              DLG_CALLER_LEG (0): caller
363  *              DLG_CALLEE_LEG (1): callee
364  */
365 static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
366 {
367         uac_req_t uac_r;
368         dlg_t* dialog_info;
369         str met = {"BYE", 3};
370         int result;
371         dlg_iuid_t *iuid = NULL;
372         str lhdrs;
373
374         /* do not send BYE request for non-confirmed dialogs (not supported) */
375         if (cell->state != DLG_STATE_CONFIRMED_NA && cell->state != DLG_STATE_CONFIRMED) {
376                 LM_ERR("terminating non-confirmed dialogs not supported\n");
377                 return -1;
378         }
379
380         /*verify direction*/
381
382         if ((dialog_info = build_dlg_t(cell, dir)) == 0){
383                 LM_ERR("failed to create dlg_t\n");
384                 goto err;
385         }
386
387         /* safety bump of cseq if prack was involved in call setup */
388         if(cell->iflags & DLG_IFLAG_PRACK) {
389                 dialog_info->loc_seq.value += 80;
390         }
391
392         LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");
393
394         iuid = dlg_get_iuid_shm_clone(cell);
395         if(iuid==NULL)
396         {
397                 LM_ERR("failed to create dialog unique id clone\n");
398                 goto err;
399         }
400
401         lhdrs = *hdrs;
402
403         if(dir==DLG_CALLEE_LEG && dlg_lreq_callee_headers.len>0) {
404                 /* space allocated in hdrs->s by build_extra_hdrs() */
405                 memcpy(lhdrs.s+lhdrs.len, dlg_lreq_callee_headers.s,
406                                 dlg_lreq_callee_headers.len);
407                 lhdrs.len += dlg_lreq_callee_headers.len;
408                 if(dlg_lreq_callee_headers.s[dlg_lreq_callee_headers.len-1]!='\n') {
409                         memcpy(lhdrs.s+lhdrs.len, CRLF, CRLF_LEN);
410                         lhdrs.len += CRLF_LEN;
411                 }
412         }
413
414         set_uac_req(&uac_r, &met, &lhdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
415                                 bye_reply_cb, (void*)iuid);
416         result = d_tmb.t_request_within(&uac_r);
417
418         if(result < 0){
419                 LM_ERR("failed to send the BYE request\n");
420                 goto err;
421         }
422
423         free_tm_dlg(dialog_info);
424
425         LM_DBG("BYE sent to %s\n", (dir==0)?"caller":"callee");
426         return 0;
427
428 err:
429         if(dialog_info)
430                 free_tm_dlg(dialog_info);
431         return -1;
432 }
433
434
435 /* send keep-alive
436  * dlg - pointer to a struct dlg_cell
437  * dir - direction: the request will be sent to:
438  *              DLG_CALLER_LEG (0): caller
439  *              DLG_CALLEE_LEG (1): callee
440  */
441 int dlg_send_ka(dlg_cell_t *dlg, int dir)
442 {
443         uac_req_t uac_r;
444         dlg_t* di;
445         str met = {"OPTIONS", 7};
446         int result;
447         dlg_iuid_t *iuid = NULL;
448
449         /* do not send KA request for non-confirmed dialogs (not supported) */
450         if (dlg->state != DLG_STATE_CONFIRMED) {
451                 LM_DBG("skipping non-confirmed dialogs\n");
452                 return 0;
453         }
454
455         /* build tm dlg by direction */
456         if ((di = build_dlg_t(dlg, dir)) == 0){
457                 LM_ERR("failed to create dlg_t\n");
458                 goto err;
459         }
460
461         /* tm increases cseq value, decrease it no to make it invalid
462          * - dialog is ended on timeout (408) or C/L does not exist (481) */
463         if(di->loc_seq.value>1)
464                 di->loc_seq.value -= 2;
465         else
466                 di->loc_seq.value -= 1;
467
468         LM_DBG("sending OPTIONS to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");
469
470         iuid = dlg_get_iuid_shm_clone(dlg);
471         if(iuid==NULL)
472         {
473                 LM_ERR("failed to create dialog unique id clone\n");
474                 goto err;
475         }
476
477         if(dir==DLG_CALLEE_LEG && dlg_lreq_callee_headers.len>0) {
478                 set_uac_req(&uac_r, &met, &dlg_lreq_callee_headers, NULL, di,
479                                 TMCB_LOCAL_COMPLETED, dlg_ka_cb_dst, (void*)iuid);
480         } else {
481                 set_uac_req(&uac_r, &met, NULL, NULL, di, TMCB_LOCAL_COMPLETED,
482                                 (dir==DLG_CALLEE_LEG)?dlg_ka_cb_dst:dlg_ka_cb_src, (void*)iuid);
483         }
484         result = d_tmb.t_request_within(&uac_r);
485
486         if(result < 0){
487                 LM_ERR("failed to send the OPTIONS request\n");
488                 goto err;
489         }
490
491         free_tm_dlg(di);
492
493         LM_DBG("keep-alive sent to %s\n", (dir==0)?"caller":"callee");
494         return 0;
495
496 err:
497         if(di)
498                 free_tm_dlg(di);
499         return -1;
500 }
501
502
503 int dlg_bye(struct dlg_cell *dlg, str *hdrs, int side)
504 {
505         str all_hdrs = { 0, 0 };
506         int ret;
507
508         if(side==DLG_CALLER_LEG)
509         {
510                 if(dlg->dflags&DLG_FLAG_CALLERBYE)
511                         return -1;
512                 dlg->dflags |= DLG_FLAG_CALLERBYE;
513         } else {
514                 if(dlg->dflags&DLG_FLAG_CALLEEBYE)
515                         return -1;
516                 dlg->dflags |= DLG_FLAG_CALLEEBYE;
517         }
518         if ((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0)
519         {
520                 LM_ERR("failed to build dlg headers\n");
521                 return -1;
522         }
523         ret = send_bye(dlg, side, &all_hdrs);
524         pkg_free(all_hdrs.s);
525
526         dlg_run_event_route(dlg, NULL, dlg->state, DLG_STATE_DELETED);
527
528         return ret;
529 }
530
531 int dlg_bye_all(struct dlg_cell *dlg, str *hdrs)
532 {
533         str all_hdrs = { 0, 0 };
534         int ret;
535
536         /* run dialog terminated callbacks */
537         run_dlg_callbacks( DLGCB_TERMINATED, dlg, NULL, NULL, DLG_DIR_NONE, 0);
538
539         if ((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0)
540         {
541                 LM_ERR("failed to build dlg headers\n");
542                 return -1;
543         }
544
545         ret = send_bye(dlg, DLG_CALLER_LEG, &all_hdrs);
546         ret |= send_bye(dlg, DLG_CALLEE_LEG, &all_hdrs);
547         
548         pkg_free(all_hdrs.s);
549
550         dlg_run_event_route(dlg, NULL, dlg->state, DLG_STATE_DELETED);
551
552         return ret;
553
554 }
555