b1898c247e46db640f943ada5bb87ad372bbf97f
[sip-router] / modules / tm / dlg.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *   info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  * History:
28  * -------
29  * 2003-03-29 Created by janakj
30  * 2003-07-08 added wrapper to calculate_hooks, needed by b2bua (dcm)
31  */
32
33
34 #include <string.h>
35 #include "../../mem/shm_mem.h"
36 #include "../../dprint.h"
37 #include "../../parser/contact/parse_contact.h"
38 #include "../../parser/parse_to.h"
39 #include "../../parser/parse_from.h"
40 #include "../../parser/parse_uri.h"
41 #include "../../trim.h"
42 #include "../../ut.h"
43 #include "../../config.h"
44 #include "dlg.h"
45 #include "t_reply.h"
46 #include "../../parser/parser_f.h"
47
48 /* next added to allow automatical tag generation */
49 #include "callid.h"
50 #include "uac.h"
51
52 #define NORMAL_ORDER 0  /* Create route set in normal order - UAS */
53 #define REVERSE_ORDER 1 /* Create route set in reverse order - UAC */
54
55 #define ROUTE_PREFIX "Route: "
56 #define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX) - 1)
57
58 #define ROUTE_SEPARATOR "," CRLF "       "
59 #define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
60
61
62 /*** Temporary hack ! */
63 /*
64  * This function skips name part
65  * uri parsed by parse_contact must be used
66  * (the uri must not contain any leading or
67  *  trailing part and if angle bracket were
68  *  used, right angle bracket must be the
69  *  last character in the string)
70  *
71  * _s will be modified so it should be a tmp
72  * copy
73  */
74 void get_raw_uri(str* _s)
75 {
76         char* aq;
77         
78         if (_s->s[_s->len - 1] == '>') {
79                 aq = find_not_quoted(_s, '<');
80                 _s->len -= aq - _s->s + 2;
81                 _s->s = aq + 1;
82         }
83 }
84
85
86 /*
87  * Make a copy of a str structure using shm_malloc
88  */
89 static inline int str_duplicate(str* _d, str* _s)
90 {
91         _d->s = shm_malloc(_s->len);
92         if (!_d->s) {
93                 LOG(L_ERR, "str_duplicate(): No memory left\n");
94                 return -1;
95         }
96         
97         memcpy(_d->s, _s->s, _s->len);
98         _d->len = _s->len;
99         return 0;
100 }
101
102
103 /*
104  * Calculate dialog hooks
105  */
106 static inline int calculate_hooks(dlg_t* _d)
107 {
108         str* uri;
109         struct sip_uri puri;
110         param_hooks_t hooks;
111         param_t* params;
112
113         if (_d->route_set) {
114                 uri = &_d->route_set->nameaddr.uri;
115                 if (parse_uri(uri->s, uri->len, &puri) < 0) {
116                         LOG(L_ERR, "calculate_hooks(): Error while parsing URI\n");
117                         return -1;
118                 }
119
120                 if (parse_params(&puri.params, CLASS_URI, &hooks, &params) < 0) {
121                         LOG(L_ERR, "calculate_hooks(): Error while parsing parameters\n");
122                         return -2;
123                 }
124                 free_params(params);
125                 
126                 if (hooks.uri.lr) {
127                         if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
128                         else _d->hooks.request_uri = &_d->rem_uri;
129                         _d->hooks.next_hop = &_d->route_set->nameaddr.uri;
130                         _d->hooks.first_route = _d->route_set;
131                 } else {
132                         _d->hooks.request_uri = &_d->route_set->nameaddr.uri;
133                         _d->hooks.next_hop = _d->hooks.request_uri;
134                         _d->hooks.first_route = _d->route_set->next;
135                         if (_d->rem_target.len > 0) 
136                                 _d->hooks.last_route = &_d->rem_target;
137                         else 
138                                 _d->hooks.last_route = NULL; /* ? */
139                 }
140         } else {
141                 if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
142                 else _d->hooks.request_uri = &_d->rem_uri;
143                 _d->hooks.next_hop = _d->hooks.request_uri;
144         }
145
146         if ((_d->hooks.request_uri) && (_d->hooks.request_uri->s) && (_d->hooks.request_uri->len)) {
147                 _d->hooks.ru.s = _d->hooks.request_uri->s;
148                 _d->hooks.ru.len = _d->hooks.request_uri->len;
149                 _d->hooks.request_uri = &_d->hooks.ru;
150                 get_raw_uri(_d->hooks.request_uri);
151         }
152         if ((_d->hooks.next_hop) && (_d->hooks.next_hop->s) && (_d->hooks.next_hop->len)) {
153                 _d->hooks.nh.s = _d->hooks.next_hop->s;
154                 _d->hooks.nh.len = _d->hooks.next_hop->len;
155                 _d->hooks.next_hop = &_d->hooks.nh;
156                 get_raw_uri(_d->hooks.next_hop);
157         }
158
159         return 0;
160 }
161
162 /*
163  * wrapper to calculate_hooks
164  * added by dcm
165  */
166 int w_calculate_hooks(dlg_t* _d)
167 {
168         return calculate_hooks(_d);
169 }
170
171 /*
172  * Create a new dialog
173  */
174 int new_dlg_uac(str* _cid, str* _ltag, unsigned int _lseq, str* _luri, str* _ruri, dlg_t** _d)
175 {
176         dlg_t* res;
177         str generated_cid;
178         str generated_ltag;
179
180         if (!_cid) { /* if not given, compute new one */
181                 generate_callid(&generated_cid);
182                 _cid = &generated_cid;
183         }
184         if (_cid && (!_ltag)) { /* if not given, compute new one */
185                 generate_fromtag(&generated_ltag, _cid);
186                 _ltag = &generated_ltag;
187         }
188         if (_lseq == 0) _lseq = DEFAULT_CSEQ;
189
190         if (!_cid || !_ltag || !_luri || !_ruri || !_d) {
191                 LOG(L_ERR, "new_dlg_uac(): Invalid parameter value\n");
192                 return -1;
193         }
194
195         res = (dlg_t*)shm_malloc(sizeof(dlg_t));
196         if (res == 0) {
197                 LOG(L_ERR, "new_dlg_uac(): No memory left\n");
198                 return -2;
199         }
200
201              /* Clear everything */     
202         memset(res, 0, sizeof(dlg_t));
203         
204              /* Make a copy of Call-ID */
205         if (str_duplicate(&res->id.call_id, _cid) < 0) return -3;
206              /* Make a copy of local tag (usually From tag) */
207         if (str_duplicate(&res->id.loc_tag, _ltag) < 0) return -4;
208              /* Make a copy of local URI (usually From) */
209         if (str_duplicate(&res->loc_uri, _luri) < 0) return -5;
210              /* Make a copy of remote URI (usually To) */
211         if (str_duplicate(&res->rem_uri, _ruri) < 0) return -6;
212              /* Make a copy of local sequence (usually CSeq) */
213         res->loc_seq.value = _lseq;
214              /* And mark it as set */
215         res->loc_seq.is_set = 1;
216
217         *_d = res;
218
219         if (calculate_hooks(*_d) < 0) {
220                 LOG(L_ERR, "new_dlg_uac(): Error while calculating hooks\n");
221                 /* FIXME: free everything here */
222                 shm_free(res);
223                 return -2;
224         }
225         
226         return 0;
227 }
228
229
230 /*
231  * Parse Contact header field body and extract URI
232  * Does not parse headers !!
233  */
234 static inline int get_contact_uri(struct sip_msg* _m, str* _uri)
235 {
236         contact_t* c;
237
238         _uri->len = 0;
239         _uri->s = 0;
240
241         if (!_m->contact) return 1;
242
243         if (parse_contact(_m->contact) < 0) {
244                 LOG(L_ERR, "get_contact_uri(): Error while parsing Contact body\n");
245                 return -2;
246         }
247
248         c = ((contact_body_t*)_m->contact->parsed)->contacts;
249
250         if (!c) {
251                 LOG(L_ERR, "get_contact_uri(): Empty body or * contact\n");
252                 return -3;
253         }
254
255         _uri->s = c->uri.s;
256         _uri->len = c->uri.len;
257         return 0;
258 }
259
260
261 /*
262  * Extract tag from To header field of a response
263  * Doesn't parse message headers !!
264  */
265 static inline int get_to_tag(struct sip_msg* _m, str* _tag)
266 {
267         if (!_m->to) {
268                 LOG(L_ERR, "get_to_tag(): To header field missing\n");
269                 return -1;
270         }
271
272         if (get_to(_m)->tag_value.len) {
273                 _tag->s = get_to(_m)->tag_value.s;
274                 _tag->len = get_to(_m)->tag_value.len;
275         } else {
276                 _tag->len = 0;
277         }
278
279         return 0;
280 }
281
282
283 /*
284  * Extract tag from From header field of a request
285  */
286 static inline int get_from_tag(struct sip_msg* _m, str* _tag)
287 {
288         if (parse_from_header(_m) == -1) {
289                 LOG(L_ERR, "get_from_tag(): Error while parsing From header\n");
290                 return -1;
291         }
292
293         if (get_from(_m)->tag_value.len) {
294                 _tag->s = get_from(_m)->tag_value.s;
295                 _tag->len = get_from(_m)->tag_value.len;
296         } else {
297                 _tag->len = 0;
298         }
299
300         return 0;
301 }
302
303
304 /*
305  * Extract Call-ID value
306  * Doesn't parse headers !!
307  */
308 static inline int get_callid(struct sip_msg* _m, str* _cid)
309 {
310         if (_m->callid == 0) {
311                 LOG(L_ERR, "get_callid(): Call-ID not found\n");
312                 return -1;
313         }
314
315         _cid->s = _m->callid->body.s;
316         _cid->len = _m->callid->body.len;
317         trim(_cid);
318         return 0;
319 }
320
321 static rr_t *revert_route(rr_t *r)
322 {
323         rr_t *a, *b;
324
325         a = NULL;
326
327         while (r) {
328                 b = r->next;
329                 r->next = a;
330                 a = r;
331                 r = b;
332         }
333
334         return a;
335 }
336
337 /*
338  * Create a copy of route set either in normal or reverse order
339  */
340 static inline int get_route_set(struct sip_msg* _m, rr_t** _rs, unsigned char _order)
341 {
342         struct hdr_field* ptr;
343         rr_t* last, *p, *t;
344         
345         last = 0;
346
347         ptr = _m->record_route;
348         while(ptr) {
349                 if (ptr->type == HDR_RECORDROUTE_T) {
350                         if (parse_rr(ptr) < 0) {
351                                 LOG(L_ERR, "get_route_set(): Error while parsing Record-Route body\n");
352                                 goto error;
353                         }
354
355                         p = (rr_t*)ptr->parsed;
356                         if (shm_duplicate_rr(&t, p) < 0) {
357                                 LOG(L_ERR, "get_route_set(): Error while duplicating rr_t\n");
358                                 goto error;
359                         }
360                         if (!*_rs) *_rs = t;
361                         if (last) last->next = t;
362                         last = t;
363                         while (last->next) last = last->next; /* !!! there may be more routes in one hdr field !!! */
364
365                 }
366                 ptr = ptr->next;
367         }
368         if ((*_rs) && (_order != NORMAL_ORDER)) {
369                 /* better to revert the route outside of cycle above */
370                 *_rs = revert_route(*_rs);
371         }
372         
373         return 0;
374
375  error:
376         shm_free_rr(_rs);
377         return -1;
378 }
379
380 /*
381  * Extract method from CSeq header field
382  */
383 static inline int get_cseq_method(struct sip_msg* _m, str* _method)
384 {
385         if (!_m->cseq && ((parse_headers(_m, HDR_CSEQ_F, 0) == -1) || !_m->cseq)) {
386                 LOG(L_ERR, "get_cseq_method(): Error while parsing CSeq\n");
387                 return -1;
388         }
389
390         _method->s = get_cseq(_m)->method.s;
391         _method->len = get_cseq(_m)->method.len;
392         return 0;
393 }
394
395
396 static inline int refresh_dialog_resp(struct sip_msg* _m, 
397                 target_refresh_t is_target_refresh)
398 {
399         str method;
400         
401         switch (is_target_refresh) {
402                 case IS_NOT_TARGET_REFRESH: 
403                         return 0;
404                 case IS_TARGET_REFRESH: 
405                         return 1;
406                 case TARGET_REFRESH_UNKNOWN: 
407                         if (get_cseq_method(_m, &method) < 0) return 0; /* error */
408                         if ((method.len == 6) && !memcmp("INVITE", method.s, 6)) 
409                                 return 1;
410                         else return 0;
411         }
412         return 0;
413 }
414                 
415 static inline int refresh_dialog_req(struct sip_msg* _m, target_refresh_t is_target_refresh)
416 {
417         switch (is_target_refresh) {
418                 case IS_NOT_TARGET_REFRESH: 
419                         return 0;
420                 case IS_TARGET_REFRESH: 
421                         return 1;
422                 case TARGET_REFRESH_UNKNOWN: 
423                         return (_m->first_line.u.request.method_value == METHOD_INVITE);
424                         break;
425         }
426         return 0;
427 }
428
429 /*
430  * Extract all necessary information from a response and put it
431  * in a dialog structure
432  */
433 static inline int response2dlg(struct sip_msg* _m, dlg_t* _d)
434 {
435         str contact, rtag;
436
437              /* Parse the whole message, we will need all Record-Route headers */
438         if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
439                 LOG(L_ERR, "response2dlg(): Error while parsing headers\n");
440                 return -1;
441         }
442         
443         if (get_contact_uri(_m, &contact) < 0) return -2;
444         if (_d->rem_target.s) {
445                 shm_free(_d->rem_target.s);
446                 _d->rem_target.s = 0; 
447                 _d->rem_target.len = 0;
448         }
449         if (contact.len && str_duplicate(&_d->rem_target, &contact) < 0) return -3;
450         
451         if (get_to_tag(_m, &rtag) < 0) goto err1;
452         if (rtag.len && str_duplicate(&_d->id.rem_tag, &rtag) < 0) goto err1;
453         
454         if (get_route_set(_m, &_d->route_set, REVERSE_ORDER) < 0) goto err2;
455
456         return 0;
457  err2:
458         if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s);
459         _d->id.rem_tag.s = 0;
460         _d->id.rem_tag.len = 0;
461
462  err1:
463         if (_d->rem_target.s) shm_free(_d->rem_target.s);
464         _d->rem_target.s = 0;
465         _d->rem_target.len = 0;
466         return -4;
467 }
468
469
470 /*
471  * Handle dialog in DLG_NEW state, we will be processing the
472  * first response
473  */
474 static inline int dlg_new_resp_uac(dlg_t* _d, struct sip_msg* _m)
475 {
476         int code;
477              /*
478               * Dialog is in DLG_NEW state, we will copy remote
479               * target URI, remote tag if present, and route-set 
480               * if present. And we will transit into DLG_CONFIRMED 
481               * if the response was 2xx and to DLG_DESTROYED if the 
482               * request was a negative final response.
483               */
484
485         code = _m->first_line.u.reply.statuscode;
486
487         if (code < 200) {
488                      /* A provisional response, do nothing, we could
489                       * update remote tag and route set but we will do that
490                       * for a positive final response anyway and I don't want
491                       * bet on presence of these fields in provisional responses
492                       *
493                       * Send a request to jan@iptel.org if you need to update
494                       * the structures here
495                       */
496         } else if ((code >= 200) && (code < 299)) {
497                      /* A final response, update the structures and transit
498                       * into DLG_CONFIRMED
499                       */
500                 if (response2dlg(_m, _d) < 0) return -1;
501                 _d->state = DLG_CONFIRMED;
502
503                 if (calculate_hooks(_d) < 0) {
504                         LOG(L_ERR, "dlg_new_resp_uac(): Error while calculating hooks\n");
505                         return -2;
506                 }
507         } else {
508                      /* 
509                       * A negative final response, mark the dialog as destroyed
510                       * Again, I do not update the structures here because it
511                       * makes no sense to me, a dialog shouldn't be used after
512                       * it is destroyed
513                       */
514                 _d->state = DLG_DESTROYED;
515                      /* Signalize the termination with positive return value */
516                 return 1;
517         }
518
519         return 0;
520 }
521
522
523 /*
524  * Handle dialog in DLG_EARLY state, we will be processing either
525  * next provisional response or a final response
526  */
527 static inline int dlg_early_resp_uac(dlg_t* _d, struct sip_msg* _m)
528 {
529         int code;
530         code = _m->first_line.u.reply.statuscode;       
531
532         if (code < 200) {
533                      /* We are in early state already, do nothing
534                       */
535         } else if ((code >= 200) && (code <= 299)) {
536                 /* Warning - we can handle here response for non-initial request (for
537                  * example UPDATE within early INVITE/BYE dialog) and move into
538                  * confirmed state may be error! But this depends on dialog type... */
539                 
540                      /* Same as in dlg_new_resp_uac */
541                      /* A final response, update the structures and transit
542                       * into DLG_CONFIRMED
543                       */
544                 if (response2dlg(_m, _d) < 0) return -1;
545                 _d->state = DLG_CONFIRMED;
546
547                 if (calculate_hooks(_d) < 0) {
548                         LOG(L_ERR, "dlg_early_resp_uac(): Error while calculating hooks\n");
549                         return -2;
550                 }
551         } else {
552                      /* Else terminate the dialog */
553                 _d->state = DLG_DESTROYED;
554                      /* Signalize the termination with positive return value */
555                 return 1;
556         }
557
558         return 0;
559 }
560
561
562 /*
563  * Handle dialog in DLG_CONFIRMED state, we will be processing
564  * a response to a request sent within a dialog
565  */
566 static inline int dlg_confirmed_resp_uac(dlg_t* _d, struct sip_msg* _m, 
567                 target_refresh_t is_target_refresh)
568 {
569         int code;
570         str contact;
571
572         code = _m->first_line.u.reply.statuscode;       
573
574              /* Dialog has been already confirmed, that means we received
575               * a response to a request sent within the dialog. We will
576               * update remote target URI if and only if the message sent was
577               * a target refresher. 
578               */
579
580              /* IF we receive a 481 response, terminate the dialog because
581               * the remote peer indicated that it didn't have the dialog
582               * state anymore, signal this termination with a positive return
583               * value
584               */
585         if (code == 481) {
586                 _d->state = DLG_DESTROYED;
587                 return 1;
588         }
589
590              /* Do nothing if not 2xx */
591         if ((code < 200) || (code >= 300)) return 0;
592         
593         if (refresh_dialog_resp(_m, is_target_refresh)) {
594                      /* Get contact if any and update remote target */
595                 if (parse_headers(_m, HDR_CONTACT_F, 0) == -1) {
596                         LOG(L_ERR, "dlg_confirmed_resp_uac(): Error while parsing headers\n");
597                         return -2;
598                 }
599
600                      /* Try to extract contact URI */
601                 if (get_contact_uri(_m, &contact) < 0) return -3;
602                      /* If there is a contact URI */
603                 if (contact.len) {
604                              /* Free old remote target if any */
605                         if (_d->rem_target.s) shm_free(_d->rem_target.s);
606                              /* Duplicate new remote target */
607                         if (str_duplicate(&_d->rem_target, &contact) < 0) return -4;
608                 }
609
610                 calculate_hooks(_d);
611         }
612
613         return 0;
614 }
615
616
617 /*
618  * A response arrived, update dialog
619  */
620 int dlg_response_uac(dlg_t* _d, struct sip_msg* _m, 
621                 target_refresh_t is_target_refresh)
622 {
623         if (!_d || !_m) {
624                 LOG(L_ERR, "dlg_response_uac(): Invalid parameter value\n");
625                 return -1;
626         }
627
628              /* The main dispatcher */
629         switch(_d->state) {
630         case DLG_NEW:       
631                 return dlg_new_resp_uac(_d, _m);
632
633         case DLG_EARLY:     
634                 return dlg_early_resp_uac(_d, _m);
635
636         case DLG_CONFIRMED: 
637                 return dlg_confirmed_resp_uac(_d, _m, is_target_refresh);
638
639         case DLG_DESTROYED:
640                 LOG(L_ERR, "dlg_response_uac(): Cannot handle destroyed dialog\n");
641                 return -2;
642         }
643
644         LOG(L_ERR, "dlg_response_uac(): Error in switch statement\n");
645         return -3;
646 }
647
648
649 /*
650  * Get CSeq number
651  * Does not parse headers !!
652  */
653 static inline int get_cseq_value(struct sip_msg* _m, unsigned int* _cs)
654 {
655         str num;
656
657         if (_m->cseq == 0) {
658                 LOG(L_ERR, "get_cseq_value(): CSeq header not found\n");
659                 return -1;
660         }
661
662         num.s = get_cseq(_m)->number.s;
663         num.len = get_cseq(_m)->number.len;
664
665         trim_leading(&num);
666         if (str2int(&num, _cs) < 0) {
667                 LOG(L_ERR, "get_cseq_value(): Error while converting cseq number\n");
668                 return -2;
669         }
670         return 0;
671 }
672
673
674 /*
675  * Copy To or From URI without tag parameter
676  */
677 static inline int get_dlg_uri(struct hdr_field* _h, str* _s)
678 {
679         struct to_param* ptr, *prev;
680         struct to_body* body;
681         char* tag = 0; /* Makes gcc happy */
682         int tag_len = 0, len;
683
684         if (!_h) {
685                 LOG(L_ERR, "get_dlg_uri(): Header field not found\n");
686                 return -1;
687         }
688
689              /* From was already parsed when extracting tag
690               * and To is parsed by default
691               */
692         
693         body = (struct to_body*)_h->parsed;
694
695         ptr = body->param_lst;
696         prev = 0;
697         while(ptr) {
698                 if (ptr->type == TAG_PARAM) break;
699                 prev = ptr;
700                 ptr = ptr->next;
701         }
702
703         if (ptr) {
704                      /* Tag param found */
705                 if (prev) {
706                         tag = prev->value.s + prev->value.len;
707                 } else {
708                         tag = body->body.s + body->body.len;
709                 }
710                 
711                 if (ptr->next) {
712                         tag_len = ptr->value.s + ptr->value.len - tag;
713                 } else {
714                         tag_len = _h->body.s + _h->body.len - tag;
715                 }
716         }
717
718         _s->s = shm_malloc(_h->body.len - tag_len);
719         if (!_s->s) {
720                 LOG(L_ERR, "get_dlg_uri(): No memory left\n");
721                 return -1;
722         }
723
724         if (tag_len) {
725                 len = tag - _h->body.s;
726                 memcpy(_s->s, _h->body.s, len);
727                 memcpy(_s->s + len, tag + tag_len, _h->body.len - len - tag_len);
728                 _s->len = _h->body.len - tag_len;
729         } else {
730                 memcpy(_s->s, _h->body.s, _h->body.len);
731                 _s->len = _h->body.len;
732         }
733
734         return 0;
735 }
736
737
738 /*
739  * Extract all information from a request 
740  * and update a dialog structure
741  */
742 static inline int request2dlg(struct sip_msg* _m, dlg_t* _d)
743 {
744         str contact, rtag, callid;
745
746         if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
747                 LOG(L_ERR, "request2dlg(): Error while parsing headers");
748                 return -1;
749         }
750
751         if (get_contact_uri(_m, &contact) < 0) return -2;
752         if (contact.len && str_duplicate(&_d->rem_target, &contact) < 0) return -3;
753         
754         if (get_from_tag(_m, &rtag) < 0) goto err1;
755         if (rtag.len && str_duplicate(&_d->id.rem_tag, &rtag) < 0) goto err1;
756
757         if (get_callid(_m, &callid) < 0) goto err2;
758         if (callid.len && str_duplicate(&_d->id.call_id, &callid) < 0) goto err2;
759
760         if (get_cseq_value(_m, &_d->rem_seq.value) < 0) goto err3;
761         _d->rem_seq.is_set = 1;
762
763         if (get_dlg_uri(_m->from, &_d->rem_uri) < 0) goto err3;
764         if (get_dlg_uri(_m->to, &_d->loc_uri) < 0) goto err4;
765
766         if (get_route_set(_m, &_d->route_set, NORMAL_ORDER) < 0) goto err5;     
767
768         return 0;
769  err5:
770         if (_d->loc_uri.s) shm_free(_d->loc_uri.s);
771         _d->loc_uri.s = 0;
772         _d->loc_uri.len = 0;
773  err4:
774         if (_d->rem_uri.s) shm_free(_d->rem_uri.s);
775         _d->rem_uri.s = 0;
776         _d->rem_uri.len = 0;
777  err3:
778         if (_d->id.call_id.s) shm_free(_d->id.call_id.s);
779         _d->id.call_id.s = 0;
780         _d->id.call_id.len = 0;
781  err2:
782         if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s);
783         _d->id.rem_tag.s = 0;
784         _d->id.rem_tag.len = 0;
785  err1:
786         if (_d->rem_target.s) shm_free(_d->rem_target.s);
787         _d->rem_target.s = 0;
788         _d->rem_target.len = 0;
789         return -4;
790 }
791
792
793 /*
794  * Establishing a new dialog, UAS side
795  */
796 int new_dlg_uas(struct sip_msg* _req, int _code, /*str* _tag,*/ dlg_t** _d)
797 {
798         dlg_t* res;
799         str tag;
800
801         if (!_req || /*!_tag ||*/ !_d) {
802                 LOG(L_ERR, "new_dlg_uas(): Invalid parameter value\n");
803                 return -1;
804         }
805
806         if ((_code < 200) || (_code > 299)) {
807                 DBG("new_dlg_uas(): Not a 2xx, no dialog created\n");
808                 return -2;
809         }
810
811         res = (dlg_t*)shm_malloc(sizeof(dlg_t));
812         if (res == 0) {
813                 LOG(L_ERR, "new_dlg_uac(): No memory left\n");
814                 return -3;
815         }
816              /* Clear everything */
817         memset(res, 0, sizeof(dlg_t));  
818
819         if (request2dlg(_req, res) < 0) {
820                 LOG(L_ERR, "new_dlg_uas(): Error while converting request to dialog\n");
821                 free_dlg(res);
822                 return -4;
823         }
824
825         tag.s = tm_tags;
826         tag.len = TOTAG_VALUE_LEN;
827         calc_crc_suffix(_req, tm_tag_suffix);
828         if (str_duplicate(&res->id.loc_tag, &tag) < 0) {
829                 free_dlg(res);
830                 return -5;
831         }
832         
833         *_d = res;
834
835         (*_d)->state = DLG_CONFIRMED;
836         if (calculate_hooks(*_d) < 0) {
837                 LOG(L_ERR, "new_dlg_uas(): Error while calculating hooks\n");
838                 free_dlg(res);
839                 return -6;
840         }
841
842         return 0;
843 }
844
845 /*
846  * UAS side - update a dialog from a request
847  */
848 int dlg_request_uas(dlg_t* _d, struct sip_msg* _m, target_refresh_t is_target_refresh)
849 {
850         str contact;
851         int cseq;
852
853         if (!_d || !_m) {
854                 LOG(L_ERR, "dlg_request_uas(): Invalid parameter value\n");
855                 return -1;
856         }
857
858              /* We must check if the request is not out of order or retransmission
859               * first, if so then we will not update anything
860               */
861         if (parse_headers(_m, HDR_CSEQ_F, 0) == -1) {
862                 LOG(L_ERR, "dlg_request_uas(): Error while parsing headers\n");
863                 return -2;
864         }
865         if (get_cseq_value(_m, (unsigned int*)&cseq) < 0) return -3;
866         if (_d->rem_seq.is_set && (cseq <= _d->rem_seq.value)) return 0;
867
868              /* Neither out of order nor retransmission -> update */
869         _d->rem_seq.value = cseq;
870         _d->rem_seq.is_set = 1;
871         
872              /* We will als update remote target URI if the message 
873               * is target refresher
874               */
875         if (refresh_dialog_req(_m, is_target_refresh)) { /* target refresher */
876                 if (parse_headers(_m, HDR_CONTACT_F, 0) == -1) {
877                         LOG(L_ERR, "dlg_request_uas(): Error while parsing headers\n");
878                         return -4;
879                 }
880                 
881                 if (get_contact_uri(_m, &contact) < 0) return -5;
882                 if (contact.len) {
883                         if (_d->rem_target.s) shm_free(_d->rem_target.s);
884                         if (str_duplicate(&_d->rem_target, &contact) < 0) return -6;
885                 }
886
887                 calculate_hooks(_d);
888                 
889         }
890
891         return 0;
892 }
893
894
895 /*
896  * Calculate length of the route set
897  */
898 int calculate_routeset_length(dlg_t* _d)
899 {
900         int len;
901         rr_t* ptr;
902
903         len = 0;
904         ptr = _d->hooks.first_route;
905
906         if (ptr) {
907                 len = ROUTE_PREFIX_LEN;
908                 len += CRLF_LEN;
909         }
910
911         while(ptr) {
912                 len += ptr->len;
913                 ptr = ptr->next;
914                 if (ptr) len += ROUTE_SEPARATOR_LEN;
915         } 
916
917         if (_d->hooks.last_route) {
918                 len += ROUTE_SEPARATOR_LEN + 2; /* < > */
919                 len += _d->hooks.last_route->len;
920         }
921
922         return len;
923 }
924
925
926 /*
927  *
928  * Print the route set
929  */
930 char* print_routeset(char* buf, dlg_t* _d)
931 {
932         rr_t* ptr;
933
934         ptr = _d->hooks.first_route;
935
936         if (ptr || _d->hooks.last_route) {
937                 memcpy(buf, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
938                 buf += ROUTE_PREFIX_LEN;
939         }
940
941         while(ptr) {
942                 memcpy(buf, ptr->nameaddr.name.s, ptr->len);
943                 buf += ptr->len;
944
945                 ptr = ptr->next;
946                 if (ptr) {
947                         memcpy(buf, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
948                         buf += ROUTE_SEPARATOR_LEN;
949                 }
950         } 
951
952         if (_d->hooks.last_route) {
953                 if (_d->hooks.first_route) {
954                         memcpy(buf, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
955                         buf += ROUTE_SEPARATOR_LEN;
956                 }
957                 memcpy(buf, "<", 1);
958                 buf++;
959                 memcpy(buf, _d->hooks.last_route->s, _d->hooks.last_route->len);
960                 buf += _d->hooks.last_route->len;
961                 *buf = '>';
962                 buf++;
963         }
964
965         if (_d->hooks.first_route || _d->hooks.last_route) {
966                 memcpy(buf, CRLF, CRLF_LEN);
967                 buf += CRLF_LEN;
968         }
969
970         return buf;
971 }
972
973
974 /*
975  * Destroy a dialog state
976  */
977 void free_dlg(dlg_t* _d)
978 {
979         if (!_d) return;
980
981         if (_d->id.call_id.s) shm_free(_d->id.call_id.s);
982         if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s);
983         if (_d->id.loc_tag.s) shm_free(_d->id.loc_tag.s);
984
985         if (_d->loc_uri.s) shm_free(_d->loc_uri.s);
986         if (_d->rem_uri.s) shm_free(_d->rem_uri.s);
987         if (_d->rem_target.s) shm_free(_d->rem_target.s);
988
989              /* Free all routes in the route set */
990         shm_free_rr(&_d->route_set);
991         shm_free(_d);
992 }
993
994
995 /*
996  * Print a dialog structure, just for debugging
997  */
998 void print_dlg(FILE* out, dlg_t* _d)
999 {
1000         fprintf(out, "====dlg_t===\n");
1001         fprintf(out, "id.call_id    : '%.*s'\n", _d->id.call_id.len, _d->id.call_id.s);
1002         fprintf(out, "id.rem_tag    : '%.*s'\n", _d->id.rem_tag.len, _d->id.rem_tag.s);
1003         fprintf(out, "id.loc_tag    : '%.*s'\n", _d->id.loc_tag.len, _d->id.loc_tag.s);
1004         fprintf(out, "loc_seq.value : %d\n", _d->loc_seq.value);
1005         fprintf(out, "loc_seq.is_set: %s\n", _d->loc_seq.is_set ? "YES" : "NO");
1006         fprintf(out, "rem_seq.value : %d\n", _d->rem_seq.value);
1007         fprintf(out, "rem_seq.is_set: %s\n", _d->rem_seq.is_set ? "YES" : "NO");
1008         fprintf(out, "loc_uri       : '%.*s'\n", _d->loc_uri.len, _d->loc_uri.s);
1009         fprintf(out, "rem_uri       : '%.*s'\n", _d->rem_uri.len, _d->rem_uri.s);
1010         fprintf(out, "rem_target    : '%.*s'\n", _d->rem_target.len, _d->rem_target.s);
1011         fprintf(out, "secure:       : %d\n", _d->secure);
1012         fprintf(out, "state         : ");
1013         switch(_d->state) {
1014         case DLG_NEW:       fprintf(out, "DLG_NEW\n");       break;
1015         case DLG_EARLY:     fprintf(out, "DLG_EARLY\n");     break;
1016         case DLG_CONFIRMED: fprintf(out, "DLG_CONFIRMED\n"); break;
1017         case DLG_DESTROYED: fprintf(out, "DLG_DESTROYED\n"); break;
1018         }
1019         print_rr(out, _d->route_set);
1020         if (_d->hooks.request_uri) 
1021                 fprintf(out, "hooks.request_uri: '%.*s'\n", _d->hooks.request_uri->len, _d->hooks.request_uri->s);
1022         if (_d->hooks.next_hop) 
1023                 fprintf(out, "hooks.next_hop   : '%.*s'\n", _d->hooks.next_hop->len, _d->hooks.next_hop->s);
1024         if (_d->hooks.first_route) 
1025                 fprintf(out, "hooks.first_route: '%.*s'\n", _d->hooks.first_route->len, _d->hooks.first_route->nameaddr.name.s);
1026         if (_d->hooks.last_route)
1027                 fprintf(out, "hooks.last_route : '%.*s'\n", _d->hooks.last_route->len, _d->hooks.last_route->s);
1028         
1029         fprintf(out, "====dlg_t====\n");
1030 }