3d634540e61fc9235480d25e91e8ff4fc26f94d2
[sip-router] / src / modules / tm / t_msgbuilder.c
1 /*
2  * message printing
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio 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  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include "defs.h"
25
26 #ifdef EXTRA_DEBUG
27 #include <assert.h>
28 #endif
29 #include "../../core/comp_defs.h"
30 #include "../../core/hash_func.h"
31 #include "../../core/globals.h"
32 #include "t_funcs.h"
33 #include "../../core/dprint.h"
34 #include "../../core/config.h"
35 #include "../../core/parser/parser_f.h"
36 #include "../../core/parser/parse_to.h"
37 #include "../../core/ut.h"
38 #include "../../core/srapi.h"
39 #include "../../core/parser/msg_parser.h"
40 #include "../../core/parser/contact/parse_contact.h"
41 #include "lw_parser.h"
42 #include "t_msgbuilder.h"
43 #include "uac.h"
44 #ifdef USE_DNS_FAILOVER
45 #include "../../core/dns_cache.h"
46 #include "../../core/cfg_core.h" /* cfg_get(core, core_cfg, use_dns_failover) */
47 #endif
48
49
50 /* convenience macros */
51 #define memapp(_d,_s,_len) \
52         do{\
53                 memcpy((_d),(_s),(_len));\
54                 (_d) += (_len);\
55         }while(0)
56
57
58 /* Build a local request based on a previous request; main
59  * customers of this function are local ACK and local CANCEL
60  */
61 char *build_local(struct cell *Trans,unsigned int branch,
62         unsigned int *len, char *method, int method_len, str *to
63 #ifdef CANCEL_REASON_SUPPORT
64         , struct cancel_reason* reason
65 #endif /* CANCEL_REASON_SUPPORT */
66         )
67 {
68         char                *cancel_buf, *p, *via;
69         unsigned int         via_len;
70         struct hdr_field    *hdr;
71         char branch_buf[MAX_BRANCH_PARAM_LEN];
72         int branch_len;
73         str branch_str;
74         str via_id;
75         struct hostport hp;
76 #ifdef CANCEL_REASON_SUPPORT
77         int reason_len, code_len;
78         struct hdr_field *reas1, *reas_last;
79 #endif /* CANCEL_REASON_SUPPORT */
80
81         /* init */
82         via_id.s=0;
83         via_id.len=0;
84
85         /* method, separators, version: "CANCEL sip:p2@iptel.org SIP/2.0" */
86         *len=SIP_VERSION_LEN + method_len + 2 /* spaces */ + CRLF_LEN;
87         *len+=Trans->uac[branch].uri.len;
88
89         /*via*/
90         if (!t_calc_branch(Trans,  branch,
91                 branch_buf, &branch_len ))
92                 goto error;
93         branch_str.s=branch_buf;
94         branch_str.len=branch_len;
95         set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));
96 #ifdef USE_TCP
97         if (!is_local(Trans) && ((Trans->uas.request->rcv.proto==PROTO_TCP)
98 #ifdef USE_TLS
99                                 || (Trans->uas.request->rcv.proto==PROTO_TLS)
100 #endif /* USE_TLS */
101                 )){
102                 if ((via_id.s=id_builder(Trans->uas.request,
103                                                                         (unsigned int*)&via_id.len))==0){
104                         LM_ERR("id builder failed\n");
105                         /* try to continue without id */
106                 }
107         }
108 #endif /* USE_TCP */
109         via=via_builder(&via_len, &Trans->uac[branch].request.dst,
110                 &branch_str, via_id.s?&via_id:0 , &hp );
111
112         /* via_id.s not needed anylonger => free it */
113         if (via_id.s) {
114                 pkg_free(via_id.s);
115                 via_id.s=0;
116                 via_id.len=0;
117         }
118
119         if (!via) {
120                 LM_ERR("no via header got from builder\n");
121                 goto error;
122         }
123         *len+= via_len;
124         /*headers*/
125         *len+=Trans->from.len+Trans->callid.len+to->len+
126                 +Trans->cseq_n.len+1+method_len+CRLF_LEN+MAXFWD_HEADER_LEN;
127
128
129         /* copy'n'paste Route headers */
130         if (!is_local(Trans)) {
131                 for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
132                         if (hdr->type==HDR_ROUTE_T)
133                                 *len+=hdr->len;
134         }
135
136         /* User Agent */
137         if (server_signature) {
138                 *len += user_agent_hdr.len + CRLF_LEN;
139         }
140         /* Content Length, EoM */
141         *len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
142 #ifdef CANCEL_REASON_SUPPORT
143         reason_len = 0;
144         reas1 = 0;
145         reas_last = 0;
146         /* compute reason size (if no reason or disabled => reason_len == 0)*/
147         if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
148                 if (likely(reason->cause > 0 &&
149                                         cfg_get(tm, tm_cfg, local_cancel_reason))){
150                         /* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */
151                         reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN +
152                                 (reason->u.text.s?
153                                         REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) +
154                                 CRLF_LEN;
155                 } else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS &&
156                                         !(Trans->flags & T_NO_E2E_CANCEL_REASON))) {
157                         reason_len = reason->u.packed_hdrs.len;
158                 } else if (reason->cause == CANCEL_REAS_RCVD_CANCEL &&
159                                         reason->u.e2e_cancel &&
160                                         !(Trans->flags & T_NO_E2E_CANCEL_REASON)) {
161                         /* parse the entire cancel, to get all the Reason headers */
162                         if(parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0)<0) {
163                                 LM_WARN("failed to parse headers\n");
164                         }
165                         for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr;
166                                         hdr; hdr=next_sibling_hdr(hdr)) {
167                                 /* hdr->len includes CRLF */
168                                 reason_len += hdr->len;
169                                 reas_last=hdr;
170                         }
171                 } else if (unlikely(reason->cause < CANCEL_REAS_MIN))
172                         LM_BUG("unhandled reason cause %d\n", reason->cause);
173         }
174         *len+= reason_len;
175 #endif /* CANCEL_REASON_SUPPORT */
176         *len+= CRLF_LEN; /* end of msg. */
177
178         cancel_buf=shm_malloc( *len+1 );
179         if (!cancel_buf) {
180                 LM_ERR("cannot allocate memory\n");
181                 goto error01;
182         }
183         p = cancel_buf;
184
185         append_str( p, method, method_len );
186         append_str( p, " ", 1 );
187         append_str( p, Trans->uac[branch].uri.s, Trans->uac[branch].uri.len);
188         append_str( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );
189
190         /* insert our via */
191         append_str(p,via,via_len);
192
193         /*other headers*/
194         append_str( p, Trans->from.s, Trans->from.len );
195         append_str( p, Trans->callid.s, Trans->callid.len );
196         append_str( p, to->s, to->len );
197
198         append_str( p, Trans->cseq_n.s, Trans->cseq_n.len );
199         append_str( p, " ", 1 );
200         append_str( p, method, method_len );
201         append_str( p, CRLF, CRLF_LEN );
202         append_str( p, MAXFWD_HEADER, MAXFWD_HEADER_LEN );
203
204         if (!is_local(Trans))  {
205                 for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
206                         if(hdr->type==HDR_ROUTE_T) {
207                                 append_str(p, hdr->name.s, hdr->len );
208                         }
209         }
210
211         /* User Agent header */
212         if (server_signature) {
213                 append_str(p, user_agent_hdr.s, user_agent_hdr.len );
214                 append_str(p, CRLF, CRLF_LEN );
215         }
216         /* Content Length */
217         append_str(p, CONTENT_LENGTH "0" CRLF, CONTENT_LENGTH_LEN + 1 + CRLF_LEN);
218 #ifdef CANCEL_REASON_SUPPORT
219         /* add reason if needed */
220         if (reason_len) {
221                 if (likely(reason->cause > 0)) {
222                         append_str(p, REASON_PREFIX, REASON_PREFIX_LEN);
223                         code_len=ushort2sbuf(reason->cause, p,
224                                                                         *len-(int)(p-cancel_buf));
225                         if (unlikely(code_len==0))
226                                 LM_BUG("not enough space to write reason code");
227                         p+=code_len;
228                         if (reason->u.text.s){
229                                 append_str(p, REASON_TEXT, REASON_TEXT_LEN);
230                                 *p='"'; p++;
231                                 append_str(p, reason->u.text.s, reason->u.text.len);
232                                 *p='"'; p++;
233                         }
234                         append_str(p, CRLF, CRLF_LEN);
235                 } else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS)) {
236                         append_str(p, reason->u.packed_hdrs.s, reason->u.packed_hdrs.len);
237                 } else if (reason->cause == CANCEL_REAS_RCVD_CANCEL) {
238                         for(hdr=reas1; hdr; hdr=next_sibling_hdr(hdr)) {
239                                 /* hdr->len includes CRLF */
240                                 append_str(p, hdr->name.s, hdr->len);
241                                 if (likely(hdr==reas_last))
242                                         break;
243                         }
244                 }
245         }
246 #endif /* CANCEL_REASON_SUPPORT */
247         append_str(p, CRLF, CRLF_LEN); /* msg. end */
248         *p=0;
249
250         pkg_free(via);
251         return cancel_buf;
252 error01:
253         pkg_free(via);
254 error:
255         return NULL;
256 }
257
258 /* Re-parsing version of build_local() function:
259  * it builds a local CANCEL or ACK (for non-200 response) request based on
260  * the previous INVITE which was sent out.
261  *
262  * Can not be used to build other type of requests!
263  */
264 char *build_local_reparse(struct cell *Trans,unsigned int branch,
265         unsigned int *len, char *method, int method_len, str *to
266 #ifdef CANCEL_REASON_SUPPORT
267         , struct cancel_reason *reason
268 #endif /* CANCEL_REASON_SUPPORT */
269         )
270 {
271         char    *invite_buf, *invite_buf_end;
272         char    *cancel_buf;
273         char    *s, *s1, *d;    /* source and destination buffers */
274         short   invite_len;
275         enum _hdr_types_t       hf_type;
276         int     first_via, to_len;
277         int cancel_buf_len;
278 #ifdef CANCEL_REASON_SUPPORT
279         int reason_len, code_len;
280         struct hdr_field *reas1, *reas_last, *hdr;
281 #endif /* CANCEL_REASON_SUPPORT */
282         int hadded = 0;
283         sr_cfgenv_t *cenv = NULL;
284
285         invite_buf = Trans->uac[branch].request.buffer;
286         invite_len = Trans->uac[branch].request.buffer_len;
287
288         if (!invite_buf || !invite_len) {
289                 LM_ERR("INVITE is missing\n");
290                 goto error;
291         }
292         if ((*invite_buf != 'I') && (*invite_buf != 'i')) {
293                 LM_ERR("trying to build with local reparse"
294                                         " for a non-INVITE request?\n");
295                 goto error;
296         }
297
298 #ifdef CANCEL_REASON_SUPPORT
299         reason_len = 0;
300         reas1 = 0;
301         reas_last = 0;
302         /* compute reason size (if no reason or disabled => reason_len == 0)*/
303         if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
304                 if (likely(reason->cause > 0 &&
305                                         cfg_get(tm, tm_cfg, local_cancel_reason))){
306                         /* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */
307                         reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN +
308                                 (reason->u.text.s?
309                                         REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) +
310                                 CRLF_LEN;
311                 } else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS &&
312                                         !(Trans->flags & T_NO_E2E_CANCEL_REASON))) {
313                         reason_len = reason->u.packed_hdrs.len;
314                 } else if (reason->cause == CANCEL_REAS_RCVD_CANCEL &&
315                                         reason->u.e2e_cancel &&
316                                         !(Trans->flags & T_NO_E2E_CANCEL_REASON)) {
317                         /* parse the entire cancel, to get all the Reason headers */
318                         if(parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0)<0) {
319                                 LM_WARN("failed to parse headers\n");
320                         }
321                         for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr;
322                                         hdr; hdr=next_sibling_hdr(hdr)) {
323                                 /* hdr->len includes CRLF */
324                                 reason_len += hdr->len;
325                                 reas_last=hdr;
326                         }
327                 } else if (unlikely(reason->cause < CANCEL_REAS_MIN))
328                         LM_BUG("unhandled reason cause %d\n", reason->cause);
329         }
330 #endif /* CANCEL_REASON_SUPPORT */
331
332         invite_buf_end = invite_buf + invite_len;
333         s = invite_buf;
334
335         /* Allocate memory for the new message.
336         The new request will be smaller than the INVITE, so the same size is enough.
337         I just extend it with the length of new To HF to be sure.
338         Ugly, but we avoid lots of checks and memory allocations this way */
339         to_len = to ? to->len : 0;
340 #ifdef CANCEL_REASON_SUPPORT
341         cancel_buf_len = invite_len + to_len + reason_len;
342 #else
343         cancel_buf_len = invite_len + to_len;
344 #endif /* CANCEL_REASON_SUPPORT */
345         cancel_buf = shm_malloc(sizeof(char)*cancel_buf_len);
346         if (!cancel_buf)
347         {
348                 LM_ERR("cannot allocate shared memory\n");
349                 goto error;
350         }
351         d = cancel_buf;
352
353         /* method name + space */
354         append_str(d, method, method_len);
355         *d = ' ';
356         d++;
357         /* skip "INVITE " and copy the rest of the line including CRLF */
358         s += 7;
359         s1 = s;
360         s = eat_line(s, invite_buf_end - s);
361         append_str(d, s1, s - s1);
362
363         cenv = sr_cfgenv_get();
364
365         /* check every header field name,
366         we must exclude and modify some of the headers */
367         first_via = 1;
368         while (s < invite_buf_end) {
369                 s1 = s;
370                 if ((*s == '\n') || (*s == '\r')) {
371                         /* end of SIP msg */
372                         hf_type = HDR_EOH_T;
373                 } else {
374                         /* parse HF name */
375                         s = lw_get_hf_name(s, invite_buf_end,
376                                                 &hf_type);
377                 }
378
379                 switch(hf_type) {
380                         case HDR_CSEQ_T:
381                                 /* find the method name and replace it */
382                                 while ((s < invite_buf_end)
383                                         && ((*s == ':') || (*s == ' ') || (*s == '\t') ||
384                                                 ((*s >= '0') && (*s <= '9')))
385                                         ) s++;
386                                 append_str(d, s1, s - s1);
387                                 append_str(d, method, method_len);
388                                 append_str(d, CRLF, CRLF_LEN);
389                                 s = lw_next_line(s, invite_buf_end);
390                                 break;
391
392                         case HDR_VIA_T:
393                                 s = lw_next_line(s, invite_buf_end);
394                                 if (first_via) {
395                                         /* copy hf */
396                                         append_str(d, s1, s - s1);
397                                         first_via = 0;
398                                 } /* else skip this line, we need olny the first via */
399                                 break;
400
401                         case HDR_TO_T:
402                                 if (to_len == 0) {
403                                         /* there is no To tag required, just copy paste
404                                          * the header */
405                                         s = lw_next_line(s, invite_buf_end);
406                                         append_str(d, s1, s - s1);
407                                 } else {
408                                         /* use the given To HF instead of the original one */
409                                         append_str(d, to->s, to->len);
410                                         /* move the pointer to the next line */
411                                         s = lw_next_line(s, invite_buf_end);
412                                 }
413                                 break;
414
415                         case HDR_FROM_T:
416                         case HDR_CALLID_T:
417                         case HDR_ROUTE_T:
418                         case HDR_MAXFORWARDS_T:
419                                 /* copy hf */
420                                 s = lw_next_line(s, invite_buf_end);
421                                 append_str(d, s1, s - s1);
422                                 break;
423
424                         case HDR_REQUIRE_T:
425                         case HDR_PROXYREQUIRE_T:
426                                 /* skip this line */
427                                 s = lw_next_line(s, invite_buf_end);
428                                 break;
429
430                         case HDR_CONTENTLENGTH_T:
431                                 /* copy hf name with 0 value */
432                                 append_str(d, s1, s - s1);
433                                 append_str(d, ": 0" CRLF, 3 + CRLF_LEN);
434                                 /* move the pointer to the next line */
435                                 s = lw_next_line(s, invite_buf_end);
436                                 break;
437
438                         case HDR_EOH_T:
439                                 /* end of SIP message found */
440 #ifdef CANCEL_REASON_SUPPORT
441                                 /* add reason if needed */
442                                 if (reason_len) {
443                                         /* if reason_len !=0, no need for any reason enabled
444                                          * checks */
445                                         if (likely(reason->cause > 0)) {
446                                                 append_str(d, REASON_PREFIX, REASON_PREFIX_LEN);
447                                                 code_len=ushort2sbuf(reason->cause, d,
448                                                                                 cancel_buf_len-(int)(d-cancel_buf));
449                                                 if (unlikely(code_len==0))
450                                                         LM_BUG("not enough space to write reason code");
451                                                 d+=code_len;
452                                                 if (reason->u.text.s){
453                                                         append_str(d, REASON_TEXT, REASON_TEXT_LEN);
454                                                         *d='"'; d++;
455                                                         append_str(d, reason->u.text.s,
456                                                                                         reason->u.text.len);
457                                                         *d='"'; d++;
458                                                 }
459                                                 append_str(d, CRLF, CRLF_LEN);
460                                         } else if (likely(reason->cause ==
461                                                                                 CANCEL_REAS_PACKED_HDRS)) {
462                                                         append_str(d, reason->u.packed_hdrs.s,
463                                                                                         reason->u.packed_hdrs.len);
464                                         } else if (reason->cause == CANCEL_REAS_RCVD_CANCEL) {
465                                                 for(hdr=reas1; hdr; hdr=next_sibling_hdr(hdr)) {
466                                                         /* hdr->len includes CRLF */
467                                                         append_str(d, hdr->name.s, hdr->len);
468                                                         if (likely(hdr==reas_last))
469                                                                 break;
470                                                 }
471                                         }
472                                 }
473 #endif /* CANCEL_REASON_SUPPORT */
474                                 /* final (end-of-headers) CRLF */
475                                 append_str(d, CRLF, CRLF_LEN);
476                                 *len = d - cancel_buf;
477                                 /* LOG(L_DBG, "DBG: build_local: %.*s\n", *len, cancel_buf); */
478                                 return cancel_buf;
479
480                         default:
481                                 s = lw_next_line(s, invite_buf_end);
482                                 hadded = 0;
483
484                                 /* uac auth headers */
485                                 if(Trans->uas.request &&
486                                                 (Trans->uas.request->msg_flags & FL_UAC_AUTH)) {
487                                         if(s1 + cenv->uac_cseq_auth.len + 2 < invite_buf_end) {
488                                                 if(s1[cenv->uac_cseq_auth.len]==':'
489                                                                 && strncmp(s1, cenv->uac_cseq_auth.s,
490                                                                         cenv->uac_cseq_auth.len)==0) {
491                                                         hadded = 1;
492                                                         append_str(d, s1, s - s1);
493                                                 } else if(s1[cenv->uac_cseq_refresh.len]==':'
494                                                                 && strncmp(s1, cenv->uac_cseq_refresh.s,
495                                                                         cenv->uac_cseq_refresh.len)==0) {
496                                                         hadded = 1;
497                                                         append_str(d, s1, s - s1);
498                                                 }
499                                         }
500                                 }
501
502                                 if(likely(hadded==0)) {
503                                         if (cfg_get(tm, tm_cfg, ac_extra_hdrs).len
504                                                         && (s1 + cfg_get(tm, tm_cfg, ac_extra_hdrs).len < invite_buf_end)
505                                                         && (strncasecmp(s1,
506                                                                         cfg_get(tm, tm_cfg, ac_extra_hdrs).s,
507                                                                         cfg_get(tm, tm_cfg, ac_extra_hdrs).len) == 0)) {
508                                                 append_str(d, s1, s - s1);
509                                         }
510                                 }
511                                 break;
512                 }
513         }
514
515         /* HDR_EOH_T was not found in the buffer, the message is corrupt */
516         LM_ERR("HDR_EOH_T was not found\n");
517
518         shm_free(cancel_buf);
519 error:
520         LM_ERR("cannot build %.*s request\n", method_len, method);
521         return NULL;
522
523 }
524
525
526 typedef struct rte {
527         rr_t* ptr;
528         /* 'ptr' above doesn't point to a mem chunk linked to a sip_msg, so it
529          * won't be free'd along with it => it must be free'd "manually" */
530         int free_rr;
531         struct rte* next;
532 } rte_t;
533
534
535 static inline void free_rte_list(struct rte* list)
536 {
537         struct rte* ptr;
538
539         while(list) {
540                 ptr = list;
541                 list = list->next;
542                 if (ptr->free_rr)
543                         free_rr(&ptr->ptr);
544                 pkg_free(ptr);
545         }
546 }
547
548
549 static inline int calc_routeset_len(struct rte* list, str* contact)
550 {
551         struct rte* ptr;
552         int ret;
553
554         if (list || contact) {
555                 ret = ROUTE_PREFIX_LEN + CRLF_LEN;
556         } else {
557                 return 0;
558         }
559
560         ptr = list;
561         while(ptr) {
562                 if (ptr != list) {
563                         ret += ROUTE_SEPARATOR_LEN;
564                 }
565                 ret += ptr->ptr->len;
566                 ptr = ptr->next;
567         }
568
569         if (contact) {
570                 if (list) ret += ROUTE_SEPARATOR_LEN;
571                 ret += 2 + contact->len;
572         }
573
574         return ret;
575 }
576
577
578 /*
579  * Print the route set
580  */
581 static inline char* print_rs(char* p, struct rte* list, str* contact)
582 {
583         struct rte* ptr;
584
585         if (list || contact) {
586                 memapp(p, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
587         } else {
588                 return p;
589         }
590
591         ptr = list;
592         while(ptr) {
593                 if (ptr != list) {
594                         memapp(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
595                 }
596
597                 memapp(p, ptr->ptr->nameaddr.name.s, ptr->ptr->len);
598                 ptr = ptr->next;
599         }
600
601         if (contact) {
602                 if (list) memapp(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
603                 *p++ = '<';
604                 append_str(p, contact->s, contact->len);
605                 *p++ = '>';
606         }
607
608         memapp(p, CRLF, CRLF_LEN);
609         return p;
610 }
611
612
613 /*
614  * Parse Contact header field body and extract URI
615  * Does not parse headers !
616  */
617 static inline int get_contact_uri(struct sip_msg* msg, str* uri)
618 {
619         contact_t* c;
620
621         uri->len = 0;
622         if (!msg->contact) return 1;
623
624         if (parse_contact(msg->contact) < 0) {
625                 LM_ERR("error while parsing Contact body\n");
626                 return -1;
627         }
628
629         c = ((contact_body_t*)msg->contact->parsed)->contacts;
630
631         if (!c) {
632                 LM_ERR("empty body or * contact\n");
633                 return -2;
634         }
635
636         *uri = c->uri;
637         return 0;
638 }
639
640 /**
641  * Extract route set from the message (out of Record-Route, if reply, OR
642  * Route, if request).
643  * The route set is returned into the "UAC-format" (keep order for Rs, reverse
644  * RRs).
645  */
646 static inline int get_uac_rs(sip_msg_t *msg, int is_req, struct rte **rtset)
647 {
648         struct hdr_field* ptr;
649         rr_t *p, *new_p;
650         struct rte *t, *head, *old_head;
651
652         head = 0;
653         for (ptr = is_req ? msg->route : msg->record_route; ptr; ptr = ptr->next) {
654                 switch (ptr->type) {
655                         case HDR_RECORDROUTE_T:
656                                 if (is_req)
657                                         continue;
658                                 break;
659                         case HDR_ROUTE_T:
660                                 if (! is_req)
661                                         continue;
662                                 break;
663                         default:
664                                 continue;
665                 }
666                 if (parse_rr(ptr) < 0) {
667                         LM_ERR("failed to parse Record-/Route HF (%d).\n", ptr->type);
668                         goto err;
669                 }
670
671                 p = (rr_t*)ptr->parsed;
672                 while(p) {
673                         if (! (t = pkg_malloc(sizeof(struct rte)))) {
674                                 LM_ERR("out of pkg mem (asked for: %d).\n",
675                                                 (int)sizeof(struct rte));
676                                 goto err;
677                         }
678                         if (is_req) {
679                                 /* in case of requests, the sip_msg structure is free'd before
680                                  * rte list is evaluated => must do a copy of it */
681                                 if (duplicate_rr(&new_p, p) < 0) {
682                                         pkg_free(t);
683                                         LM_ERR("failed to duplicate RR");
684                                         goto err;
685                                 }
686                                 t->ptr = new_p;
687                         } else {
688                                 t->ptr = p;
689                         }
690                         t->free_rr = is_req;
691                         t->next = head;
692                         head = t;
693                         p = p->next;
694                 }
695         }
696
697         if (is_req) {
698                 /* harvesting the R/RR HF above inserts at head, which suites RRs (as
699                  * they must be reversed, anyway), but not Rs => reverse once more */
700                 old_head = head;
701                 head = 0;
702                 while (old_head) {
703                         t = old_head;
704                         old_head = old_head->next;
705                         t->next = head;
706                         head = t;
707                 }
708         }
709
710         *rtset = head;
711         return 0;
712 err:
713         free_rte_list(head);
714         return -1;
715 }
716
717
718 static inline unsigned short uri2port(const struct sip_uri *puri)
719 {
720         if (puri->port.s) {
721                 return puri->port_no;
722         } else switch (puri->type) {
723                 case SIP_URI_T:
724                 case TEL_URI_T:
725                         if (puri->transport_val.len == sizeof("TLS") - 1) {
726                                 unsigned trans;
727                                 trans = puri->transport_val.s[0] | 0x20; trans <<= 8;
728                                 trans |= puri->transport_val.s[1] | 0x20; trans <<= 8;
729                                 trans |= puri->transport_val.s[2] | 0x20;
730                                 if (trans == 0x746C73) /* t l s */
731                                         return SIPS_PORT;
732                         }
733                         return SIP_PORT;
734                 case SIPS_URI_T:
735                 case TELS_URI_T:
736                         return SIPS_PORT;
737                 default:
738                         LM_BUG("unexpected URI type %d.\n", puri->type);
739         }
740         return 0;
741 }
742
743 /**
744  * Evaluate if next hop is a strict or loose router, by looking at the
745  * retr. buffer of the original INVITE.
746  * Assumes:
747  *      orig_inv is a parsed SIP message;
748  *      rtset is not NULL.
749  * @return:
750  *      F_RB_NH_LOOSE : next hop was loose router;
751  *      F_RB_NH_STRICT: nh is strict;
752  *      0 on error.
753  */
754 static unsigned long nhop_type(sip_msg_t *orig_inv, rte_t *rtset,
755                 const struct dest_info *dst_inv, str *contact)
756 {
757         struct sip_uri puri, topr_uri, lastr_uri, inv_ruri, cont_uri;
758         struct ip_addr *uri_ia;
759         union sockaddr_union uri_sau;
760         unsigned int uri_port, dst_port, inv_port, cont_port, lastr_port;
761         rte_t *last_r;
762 #ifdef TM_LOC_ACK_DO_REV_DNS
763         struct ip_addr ia;
764         struct hostent *he;
765         char **alias;
766 #endif
767
768 #define PARSE_URI(_str_, _uri_) \
769         do { \
770                 /* parse_uri() 0z the puri */ \
771                 if (parse_uri((_str_)->s, \
772                                 (_str_)->len, _uri_) < 0) { \
773                         LM_ERR("failed to parse route body '%.*s'.\n", STR_FMT(_str_)); \
774                         return 0; \
775                 } \
776         } while (0)
777
778 #define HAS_LR(_rte_) \
779         ({ \
780                 PARSE_URI(&(_rte_)->ptr->nameaddr.uri, &puri); \
781                 puri.lr.s; \
782         })
783
784 #define URI_PORT(_puri_, _port) \
785         do { \
786                 if (! (_port = uri2port(_puri_))) \
787                         return 0; \
788         } while (0)
789
790         /* examine the easy/fast & positive cases foremost */
791
792         /* [1] check if 1st route lacks ;lr */
793         LM_DBG("checking lack of ';lr' in 1st route.\n");
794         if (! HAS_LR(rtset))
795                 return F_RB_NH_STRICT;
796         topr_uri = puri; /* save 1st route's URI */
797
798         /* [2] check if last route shows ;lr */
799         LM_DBG("checking presence of ';lr' in last route.\n");
800         for (last_r = rtset; last_r->next; last_r = last_r->next)
801                 /* scroll down to last route */
802                 ;
803         if (HAS_LR(last_r))
804                 return F_RB_NH_LOOSE;
805
806         /* [3] 1st route has ;lr -> check if the destination of original INV
807          * equals the address provided by this route; if does -> loose */
808         LM_DBG("checking INVITE's destination against its first route.\n");
809         URI_PORT(&topr_uri, uri_port);
810         if (! (dst_port = su_getport(&dst_inv->to)))
811                 return 0; /* not really expected */
812         if (dst_port != uri_port)
813                 return F_RB_NH_STRICT;
814         /* if 1st route contains an IP address, comparing it against .dst */
815         if ((uri_ia = str2ip(&topr_uri.host))
816                         || (uri_ia = str2ip6(&topr_uri.host))
817                         ) {
818                 /* we have an IP address in route -> comparison can go swiftly */
819                 if (init_su(&uri_sau, uri_ia, uri_port) < 0)
820                         return 0; /* not really expected */
821                 if (su_cmp(&uri_sau, &dst_inv->to))
822                         /* ;lr and sent there */
823                         return F_RB_NH_LOOSE;
824                 else
825                         /* ;lr and NOT sent there (probably sent to RURI address) */
826                         return F_RB_NH_STRICT;
827         } else {
828                 /*if 1st route contains a name, rev resolve the .dst and compare*/
829                 LM_INFO("Failed to decode string '%.*s' in route set element as IP"
830                                 " address. Trying name resolution.\n",STR_FMT(&topr_uri.host));
831
832         /* TODO: alternatively, rev name and compare against dest. IP.  */
833 #ifdef TM_LOC_ACK_DO_REV_DNS
834                 ia.af = 0;
835                 su2ip_addr(&ia, (void *)&dst_inv->to);
836                 if (! ia.af)
837                         return 0; /* not really expected */
838                 if ((he = rev_resolvehost(&ia))) {
839                         if ((strlen(he->h_name) == topr_uri.host.len) &&
840                                         (memcmp(he->h_name, topr_uri.host.s,
841                                                         topr_uri.host.len) == 0))
842                                 return F_RB_NH_LOOSE;
843                         for (alias = he->h_aliases; *alias; alias ++)
844                                 if ((strlen(*alias) == topr_uri.host.len) &&
845                                                 (memcmp(*alias, topr_uri.host.s,
846                                                                 topr_uri.host.len) == 0))
847                                         return F_RB_NH_LOOSE;
848                         return F_RB_NH_STRICT;
849                 } else {
850                         LM_INFO("failed to resolve address '%s' to a name.\n",
851                                         ip_addr2a(&ia));
852                 }
853 #endif
854         }
855
856         LM_WARN("failed to establish with certainty the type of next hop;"
857                         " trying an educated guess.\n");
858
859         /* [4] compare (possibly updated) remote target to original RURI; if
860          * equal, a strict router's address wasn't filled in as RURI -> loose */
861         LM_DBG("checking remote target against INVITE's RURI.\n");
862         PARSE_URI(contact, &cont_uri);
863         PARSE_URI(GET_RURI(orig_inv), &inv_ruri);
864         URI_PORT(&cont_uri, cont_port);
865         URI_PORT(&inv_ruri, inv_port);
866         if ((cont_port == inv_port) && (cont_uri.host.len == inv_ruri.host.len) &&
867                         (memcmp(cont_uri.host.s, inv_ruri.host.s, cont_uri.host.len) == 0))
868                 return F_RB_NH_LOOSE;
869
870         /* [5] compare (possibly updated) remote target to last route; if equal,
871          * strict router's address might have been filled as RURI and remote
872          * target appended to route set -> strict */
873         LM_DBG("checking remote target against INVITE's last route.\n");
874         PARSE_URI(&last_r->ptr->nameaddr.uri, &lastr_uri);
875         URI_PORT(&lastr_uri, lastr_port);
876         if ((cont_port == lastr_port) &&
877                         (cont_uri.host.len == lastr_uri.host.len) &&
878                         (memcmp(cont_uri.host.s, lastr_uri.host.s,
879                                         lastr_uri.host.len) == 0))
880                 return F_RB_NH_STRICT;
881
882         LM_WARN("failed to establish the type of next hop;"
883                         " assuming loose router.\n");
884         return F_RB_NH_LOOSE;
885
886 #undef PARSE_URI
887 #undef HAS_LR
888 #undef URI_PORT
889 }
890
891 /**
892  * Evaluates the routing elements in locally originated request or reply to
893  * locally originated request.
894  * If original INVITE was in-dialog (had to-tag), it uses the
895  * routes present there (b/c the 2xx for it does not have a RR set, normally).
896  * Otherwise, use the reply (b/c the INVITE does not have yet the complete
897  * route set).
898  *
899  * @return: negative for failure; out params:
900  *  - list: route set;
901  *  - ruri: RURI to be used in ACK;
902  *  - nexthop: where to first send the ACK.
903  *
904  *  NOTE: assumes rpl's parsed to EOF!
905  *
906  */
907 static int eval_uac_routing(sip_msg_t *rpl, const struct retr_buf *inv_rb,
908                 str* contact, struct rte **list, str *ruri, str *next_hop)
909 {
910         sip_msg_t orig_inv, *sipmsg; /* reparse original INVITE */
911         rte_t *t, *prev_t, *rtset = NULL;
912         int is_req;
913         struct sip_uri puri;
914         static size_t chklen;
915         int ret = -1;
916
917         /* parse the retr. buffer */
918         memset(&orig_inv, 0, sizeof(struct sip_msg));
919         orig_inv.buf = inv_rb->buffer;
920         orig_inv.len = inv_rb->buffer_len;
921         LM_DBG("reparsing retransmission buffer of original INVITE:\n%.*s\n",
922                         (int)orig_inv.len, orig_inv.buf);
923         if (parse_msg(orig_inv.buf, orig_inv.len, &orig_inv) != 0) {
924                 LM_ERR("failed to parse retr buffer (weird!): \n%.*s\n",
925                                 (int)orig_inv.len, orig_inv.buf);
926                 return -1;
927         }
928
929         /* check if we need to look at request or reply */
930         if ((parse_headers(&orig_inv, HDR_TO_F, 0) < 0) || (! orig_inv.to)) {
931                 /* the bug is at message assembly */
932                 LM_BUG("failed to parse INVITE retr. buffer and/or extract 'To' HF:"
933                                 "\n%.*s\n", (int)orig_inv.len, orig_inv.buf);
934                 goto end;
935         }
936         if (((struct to_body *)orig_inv.to->parsed)->tag_value.len) {
937                 LM_DBG("building ACK for in-dialog INVITE (using RS in orig. INV.)\n");
938                 if (parse_headers(&orig_inv, HDR_EOH_F, 0) < 0) {
939                         LM_BUG("failed to parse INVITE retr. buffer to EOH:"
940                                         "\n%.*s\n", (int)orig_inv.len, orig_inv.buf);
941                         goto end;
942                 }
943                 sipmsg = &orig_inv;
944                 is_req = 1;
945         } else {
946                 LM_DBG("building ACK for out-of-dialog INVITE (using RS in RR set).\n");
947                 sipmsg = rpl;
948                 is_req = 0;
949         }
950
951         /* extract the route set */
952         if (get_uac_rs(sipmsg, is_req, &rtset) < 0) {
953                 LM_ERR("failed to extract route set.\n");
954                 goto end;
955         }
956
957         if (! rtset) { /* No routes */
958                 *ruri = *contact;
959                 *next_hop = *contact;
960         } else if (! is_req) { /* out of dialog req. */
961                 if (parse_uri(rtset->ptr->nameaddr.uri.s, rtset->ptr->nameaddr.uri.len,
962                                 &puri) < 0) {
963                         LM_ERR("failed to parse first route in set.\n");
964                         goto end;
965                 }
966
967                 if (puri.lr.s) { /* Next hop is loose router */
968                         *ruri = *contact;
969                         *next_hop = rtset->ptr->nameaddr.uri;
970                 } else { /* Next hop is strict router */
971                         *ruri = rtset->ptr->nameaddr.uri;
972                         *next_hop = *ruri;
973                         /* consume first route, b/c it will be put in RURI */
974                         t = rtset;
975                         rtset = rtset->next;
976                         pkg_free(t);
977                 }
978         } else {
979                 unsigned long route_flags = inv_rb->flags;
980                 LM_DBG("UAC rb flags: 0x%x.\n", (unsigned int)route_flags);
981 eval_flags:
982                 switch (route_flags & (F_RB_NH_LOOSE|F_RB_NH_STRICT)) {
983                 case 0:
984                         LM_WARN("calculate_hooks() not called when built the local UAC of "
985                                         "in-dialog request, or called with empty route set.\n");
986                         /* try to figure out what kind of hop is the next one
987                          * (strict/loose) by reading the original invite */
988                         if ((route_flags = nhop_type(&orig_inv, rtset, &inv_rb->dst,
989                                         contact))) {
990                                 LM_DBG("original request's next hop type evaluated to: 0x%x.\n",
991                                                 (unsigned int)route_flags);
992                                 goto eval_flags;
993                         } else {
994                                 LM_ERR("failed to establish what kind of router the next "
995                                                 "hop is.\n");
996                                 goto end;
997                         }
998                         break;
999                 case F_RB_NH_LOOSE:
1000                         *ruri = *contact;
1001                         *next_hop = rtset->ptr->nameaddr.uri;
1002                         break;
1003                 case F_RB_NH_STRICT:
1004                         /* find ptr to last route body that contains the (possibly) old
1005                          * remote target
1006                          */
1007                         for (t = rtset, prev_t = t; t->next; prev_t = t, t = t->next)
1008                                 ;
1009                         if ((t->ptr->len == contact->len) &&
1010                                         (memcmp(t->ptr->nameaddr.name.s, contact->s,
1011                                                         contact->len) == 0)){
1012                                 /* the remote target didn't update -> keep the whole route set,
1013                                  * including the last entry */
1014                                 /* do nothing */
1015                         } else {
1016                                 /* trash last entry and replace with new remote target */
1017                                 free_rte_list(t);
1018                                 /* compact the rr_t struct along with rte. this way, free'ing
1019                                  * it can be done along with rte chunk, independent of Route
1020                                  * header parser's allocator (using pkg/shm) */
1021                                 chklen = sizeof(struct rte) + sizeof(rr_t);
1022                                 if (! (t = pkg_malloc(chklen))) {
1023                                         ERR("out of pkg memory (%d required)\n", (int)chklen);
1024                                         /* last element was freed, unlink it */
1025                                         if(prev_t == rtset) {
1026                                                 /* there is only one elem in route set: the remote target */
1027                                                 rtset = NULL;
1028                                         } else {
1029                                                 prev_t->next = NULL;
1030                                         }
1031                                         ret = -1;
1032                                         goto end;
1033                                 }
1034                                 /* this way, .free_rr is also set to 0 (!!!) */
1035                                 memset(t, 0, chklen);
1036                                 ((rr_t *)&t[1])->nameaddr.name = *contact;
1037                                 ((rr_t *)&t[1])->len = contact->len;
1038                                 /* chain the new route elem in set */
1039                                 if (prev_t == rtset)
1040                                         /* there is only one elem in route set: the remote target */
1041                                         rtset = t;
1042                                 else
1043                                         prev_t->next = t;
1044                         }
1045
1046                         *ruri = *GET_RURI(&orig_inv); /* reuse original RURI */
1047                         *next_hop = *ruri;
1048                         break;
1049                 default:
1050                         /* probably a mem corruption */
1051                         LM_BUG("next hop of original request marked as both loose"
1052                                         " and strict router (buffer: %.*s).\n",
1053                                         inv_rb->buffer_len, inv_rb->buffer);
1054 #ifdef EXTRA_DEBUG
1055                         abort();
1056 #else
1057                         goto end;
1058 #endif
1059                 }
1060         }
1061
1062         *list = rtset;
1063         /* all went well */
1064         ret = 0;
1065 end:
1066         free_sip_msg(&orig_inv);
1067         if (ret < 0)
1068                 free_rte_list(rtset);
1069         return ret;
1070 }
1071
1072 /*
1073  * The function creates an ACK to 200 OK. Route set will be created
1074  * and parsed and the dst parameter will contain the destination to which
1075  * the request should be send. The function is used by tm when it
1076  * generates local ACK to 200 OK (on behalf of applications using uac)
1077  */
1078 char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,
1079                                         unsigned int branch, str *hdrs, str *body,
1080                                         unsigned int *len, struct dest_info* dst)
1081 {
1082         char *req_buf, *p, *via;
1083         unsigned int via_len;
1084         char branch_buf[MAX_BRANCH_PARAM_LEN];
1085         int branch_len;
1086         str branch_str;
1087         struct hostport hp;
1088         struct rte* list;
1089         str contact, ruri, *cont;
1090         str next_hop;
1091         str body_len;
1092         str _to, *to = &_to;
1093 #ifdef USE_DNS_FAILOVER
1094         struct dns_srv_handle dns_h;
1095 #endif
1096 #ifdef WITH_AS_SUPPORT
1097         /* With AS support, TM allows for external modules to generate building of
1098          * the ACK; in this case, the ACK's retransmission buffer is built once
1099          * and kept in memory (to help when retransmitted 2xx are received and ACK
1100          * must be resent).
1101          * Allocation of the string raw buffer that holds the ACK is piggy-backed
1102          * with allocation of the retransmission buffer (since both have the same
1103          * life-cycle): both the string buffer and retransm. buffer are placed
1104          * into the same allocated chunk of memory (retr. buffer first, string
1105          * buffer follows).In this case, the 'len' param is used as in-out
1106          * parameter: 'in' to give the extra space needed by the retr. buffer,
1107          * 'out' to return the lenght of the allocated string buffer.
1108          */
1109         unsigned offset = *len;
1110 #endif
1111
1112         if (parse_headers(rpl, HDR_EOH_F, 0) == -1 || !rpl->to) {
1113                 LM_ERR("Error while parsing headers.\n");
1114                 return 0;
1115         } else {
1116                 _to.s = rpl->to->name.s;
1117                 _to.len = rpl->to->len;
1118         }
1119
1120         if (get_contact_uri(rpl, &contact) < 0) {
1121                 return 0;
1122         }
1123
1124         if (eval_uac_routing(rpl, &Trans->uac[branch].request, &contact,
1125                         &list, &ruri, &next_hop) < 0) {
1126                 LM_ERR("failed to evaluate routing elements.\n");
1127                 return 0;
1128         }
1129         LM_DBG("ACK RURI: `%.*s', NH: `%.*s'.\n", STR_FMT(&ruri),
1130                         STR_FMT(&next_hop));
1131
1132         if ((contact.s != ruri.s) || (contact.len != ruri.len)) {
1133                 /* contact != ruri means that the next
1134                  * hop is a strict router, cont will be non-zero
1135                  * and print_routeset will append it at the end
1136                  * of the route set
1137                  */
1138                 cont = &contact;
1139         } else {
1140                 /* Next hop is a loose router, nothing to append */
1141                 cont = 0;
1142         }
1143
1144         /* method, separators, version: "ACK sip:p2@iptel.org SIP/2.0" */
1145         *len = SIP_VERSION_LEN + ACK_LEN + 2 /* spaces */ + CRLF_LEN;
1146         *len += ruri.len;
1147
1148         /* dst */
1149         switch(cfg_get(tm, tm_cfg, local_ack_mode)){
1150                 case 1:
1151                         /* send the local 200 ack to the same dst as the corresp. invite*/
1152                         *dst=Trans->uac[branch].request.dst;
1153                         break;
1154                 case 2:
1155                         /* send the local 200 ack to the same dst as the 200 reply source*/
1156                         init_dst_from_rcv(dst, &rpl->rcv);
1157                         dst->send_flags=rpl->fwd_send_flags;
1158                         break;
1159                 case 0:
1160                 default:
1161                         /* rfc conformant behaviour: use the next_hop determined from the
1162                          * contact and the route set */
1163 #ifdef USE_DNS_FAILOVER
1164                 if (cfg_get(core, core_cfg, use_dns_failover)){
1165                         dns_srv_handle_init(&dns_h);
1166                         if ((uri2dst(&dns_h , dst, rpl, &next_hop, PROTO_NONE)==0) ||
1167                                         (dst->send_sock==0)){
1168                                 dns_srv_handle_put(&dns_h);
1169                                 LM_ERR("no socket found\n");
1170                                 goto error;
1171                         }
1172                         dns_srv_handle_put(&dns_h); /* not needed any more */
1173                 }else{
1174                         if ((uri2dst(0 , dst, rpl, &next_hop, PROTO_NONE)==0) ||
1175                                         (dst->send_sock==0)){
1176                                 LM_ERR("no socket found\n");
1177                                 goto error;
1178                         }
1179                 }
1180 #else /* USE_DNS_FAILOVER */
1181                 if ( (uri2dst( dst, rpl, &next_hop, PROTO_NONE)==0) ||
1182                                 (dst->send_sock==0)){
1183                         LM_ERR("no socket found\n");
1184                         goto error;
1185                 }
1186 #endif /* USE_DNS_FAILOVER */
1187                 break;
1188         }
1189
1190         /* via */
1191         if (!t_calc_branch(Trans,  branch, branch_buf, &branch_len)) goto error;
1192         branch_str.s = branch_buf;
1193         branch_str.len = branch_len;
1194         set_hostport(&hp, 0);
1195         via = via_builder(&via_len, dst, &branch_str, 0, &hp);
1196         if (!via) {
1197                 LM_ERR("No via header got from builder\n");
1198                 goto error;
1199         }
1200         *len+= via_len;
1201
1202         /* headers */
1203         *len += Trans->from.len + Trans->callid.len + to->len + Trans->cseq_n.len + 1 + ACK_LEN + CRLF_LEN;
1204
1205         /* copy'n'paste Route headers */
1206
1207         *len += calc_routeset_len(list, cont);
1208
1209         /* User Agent */
1210         if (server_signature) *len += user_agent_hdr.len + CRLF_LEN;
1211         /* extra headers */
1212         if (hdrs)
1213                 *len += hdrs->len;
1214         /* body */
1215         if (body) {
1216                 body_len.s = int2str(body->len, &body_len.len);
1217                 *len += body->len;
1218         } else {
1219                 body_len.len = 0;
1220                 body_len.s = NULL; /*4gcc*/
1221                 *len += 1; /* for the (Cont-Len:) `0' */
1222         }
1223         /* Content Length, EoM */
1224         *len += CONTENT_LENGTH_LEN + body_len.len + CRLF_LEN + CRLF_LEN;
1225
1226 #if WITH_AS_SUPPORT
1227         req_buf = shm_malloc(offset + *len + 1);
1228         req_buf += offset;
1229 #else
1230         req_buf = shm_malloc(*len + 1);
1231 #endif
1232         if (!req_buf) {
1233                 LM_ERR("Cannot allocate memory (%u+1)\n", *len);
1234                 goto error01;
1235         }
1236         p = req_buf;
1237
1238         append_str( p, ACK, ACK_LEN );
1239         append_str( p, " ", 1 );
1240         append_str(p, ruri.s, ruri.len);
1241         append_str( p, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
1242
1243         /* insert our via */
1244         append_str(p, via, via_len);
1245
1246         /*other headers*/
1247         append_str(p, Trans->from.s, Trans->from.len);
1248         append_str(p, Trans->callid.s, Trans->callid.len);
1249         append_str(p, to->s, to->len);
1250
1251         append_str(p, Trans->cseq_n.s, Trans->cseq_n.len);
1252         append_str( p, " ", 1 );
1253         append_str( p, ACK, ACK_LEN);
1254         append_str(p, CRLF, CRLF_LEN);
1255
1256         /* Routeset */
1257         p = print_rs(p, list, cont);
1258
1259         /* User Agent header */
1260         if (server_signature) {
1261                 append_str(p, user_agent_hdr.s, user_agent_hdr.len);
1262                 append_str(p, CRLF, CRLF_LEN);
1263         }
1264
1265         /* extra headers */
1266         if (hdrs)
1267                 append_str(p, hdrs->s, hdrs->len);
1268
1269         /* Content Length, EoH, (body) */
1270         if (body) {
1271                 append_str(p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
1272                 append_str(p, body_len.s, body_len.len);
1273                 append_str(p, /*end crr. header*/CRLF /*EoH*/CRLF, CRLF_LEN +
1274                                 CRLF_LEN);
1275                 append_str(p, body->s, body->len);
1276         } else {
1277                 append_str(p, CONTENT_LENGTH "0" CRLF CRLF,
1278                                 CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
1279         }
1280
1281         /* EoM */
1282         *p = 0;
1283
1284         pkg_free(via);
1285         free_rte_list(list);
1286         return req_buf;
1287
1288 error01:
1289         pkg_free(via);
1290 error:
1291         free_rte_list(list);
1292         return 0;
1293 }
1294
1295
1296 /*
1297  * Convert length of body into asciiz
1298  */
1299 static inline int print_content_length(str* dest, str* body)
1300 {
1301         static char content_length[10];
1302         int len;
1303         int b_len;
1304         char* tmp;
1305
1306         /* Print Content-Length */
1307         b_len=body?body->len:0;
1308         tmp = int2str(b_len, &len);
1309         if (len >= sizeof(content_length)) {
1310                 LM_ERR("content_len too big\n");
1311                 dest->s = 0;
1312                 dest->len = 0;
1313                 return -1;
1314         }
1315         memcpy(content_length, tmp, len);
1316         dest->s = content_length;
1317         dest->len = len;
1318         return 0;
1319 }
1320
1321
1322 /*
1323  * Convert CSeq number into asciiz
1324  */
1325 static inline int print_cseq_num(str* _s, dlg_t* _d)
1326 {
1327         static char cseq[INT2STR_MAX_LEN];
1328         char* tmp;
1329         int len;
1330
1331         tmp = int2str(_d->loc_seq.value, &len);
1332         if (len > sizeof(cseq)) {
1333                 LM_ERR("cseq too big\n");
1334                 return -1;
1335         }
1336
1337         memcpy(cseq, tmp, len);
1338         _s->s = cseq;
1339         _s->len = len;
1340         return 0;
1341 }
1342
1343
1344 /*
1345  * Create Via header
1346  */
1347 static inline int assemble_via(str* dest, struct cell* t,
1348                                                                 struct dest_info* dst, int branch)
1349 {
1350         static char branch_buf[MAX_BRANCH_PARAM_LEN];
1351         char* via;
1352         int len;
1353         unsigned int via_len;
1354         str branch_str;
1355         struct hostport hp;
1356
1357         if (!t_calc_branch(t, branch, branch_buf, &len)) {
1358                 LM_ERR("branch calculation failed\n");
1359                 return -1;
1360         }
1361
1362         branch_str.s = branch_buf;
1363         branch_str.len = len;
1364
1365 #ifdef XL_DEBUG
1366         printf("!!!proto: %d\n", sock->proto);
1367 #endif
1368
1369         set_hostport(&hp, 0);
1370         via = via_builder(&via_len, dst, &branch_str, 0, &hp);
1371         if (!via) {
1372                 LM_ERR("via building failed\n");
1373                 return -2;
1374         }
1375
1376         dest->s = via;
1377         dest->len = via_len;
1378         return 0;
1379 }
1380
1381
1382 /*
1383  * Print Request-URI
1384  */
1385 static inline char* print_request_uri(char* w, str* method, dlg_t* dialog,
1386                 struct cell* t, int branch)
1387 {
1388         memapp(w, method->s, method->len);
1389         memapp(w, " ", 1);
1390
1391         t->uac[branch].uri.s = w;
1392         t->uac[branch].uri.len = dialog->hooks.request_uri->len;
1393
1394         memapp(w, dialog->hooks.request_uri->s, dialog->hooks.request_uri->len);
1395         memapp(w, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
1396
1397         return w;
1398 }
1399
1400
1401 /*
1402  * Print To header field
1403  */
1404 static inline char* print_to(char* w, dlg_t* dialog, struct cell* t, int bracket)
1405 {
1406         t->to.s = w;
1407         t->to.len = TO_LEN + dialog->rem_uri.len + CRLF_LEN
1408                 + (((dialog->rem_uri.s[dialog->rem_uri.len - 1]!='>'))?2:0);
1409
1410         memapp(w, TO, TO_LEN);
1411         if(bracket) memapp(w, "<", 1);
1412         memapp(w, dialog->rem_uri.s, dialog->rem_uri.len);
1413         if(bracket) memapp(w, ">", 1);
1414
1415         if (dialog->id.rem_tag.len) {
1416                 t->to.len += TOTAG_LEN + dialog->id.rem_tag.len ;
1417                 memapp(w, TOTAG, TOTAG_LEN);
1418                 memapp(w, dialog->id.rem_tag.s, dialog->id.rem_tag.len);
1419         }
1420
1421         memapp(w, CRLF, CRLF_LEN);
1422         return w;
1423 }
1424
1425
1426 /*
1427  * Print From header field
1428  */
1429 static inline char* print_from(char* w, dlg_t* dialog, struct cell* t, int bracket)
1430 {
1431         t->from.s = w;
1432         t->from.len = FROM_LEN + dialog->loc_uri.len + CRLF_LEN
1433                 + ((dialog->loc_uri.s[dialog->loc_uri.len - 1]!='>')?2:0);
1434
1435         memapp(w, FROM, FROM_LEN);
1436         if(bracket) memapp(w, "<", 1);
1437         memapp(w, dialog->loc_uri.s, dialog->loc_uri.len);
1438         if(bracket) memapp(w, ">", 1);
1439
1440         if (dialog->id.loc_tag.len) {
1441                 t->from.len += FROMTAG_LEN + dialog->id.loc_tag.len;
1442                 memapp(w, FROMTAG, FROMTAG_LEN);
1443                 memapp(w, dialog->id.loc_tag.s, dialog->id.loc_tag.len);
1444         }
1445
1446         memapp(w, CRLF, CRLF_LEN);
1447         return w;
1448 }
1449
1450
1451 /*
1452  * Print CSeq header field
1453  */
1454 char* print_cseq_mini(char* target, str* cseq, str* method) {
1455         memapp(target, CSEQ, CSEQ_LEN);
1456         memapp(target, cseq->s, cseq->len);
1457         memapp(target, " ", 1);
1458         memapp(target, method->s, method->len);
1459         return target;
1460 }
1461
1462 static inline char* print_cseq(char* w, str* cseq, str* method, struct cell* t)
1463 {
1464         t->cseq_n.s = w;
1465         /* don't include method name and CRLF -- subsequent
1466          * local requests ACK/CANCEL will add their own */
1467         t->cseq_n.len = CSEQ_LEN + cseq->len;
1468         w = print_cseq_mini(w, cseq, method);
1469         return w;
1470 }
1471
1472 /*
1473  * Print Call-ID header field
1474  * created an extra function for pure header field creation,
1475  * that is used by t_cancel for t_uac_cancel FIFO function.
1476  */
1477 char* print_callid_mini(char* target, str callid) {
1478         memapp(target, CALLID, CALLID_LEN);
1479         memapp(target, callid.s, callid.len);
1480         memapp(target, CRLF, CRLF_LEN);
1481         return target;
1482 }
1483
1484 static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t)
1485 {
1486         /* begins with CRLF, not included in t->callid, don`t know why...?!? */
1487         memapp(w, CRLF, CRLF_LEN);
1488         t->callid.s = w;
1489         t->callid.len = CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;
1490
1491         w = print_callid_mini(w, dialog->id.call_id);
1492         return w;
1493 }
1494
1495
1496 /*
1497  * Create a request
1498  */
1499 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog,
1500                 int branch, struct cell *t, int* len, struct dest_info* dst)
1501 {
1502         char* buf, *w, *p;
1503         str content_length, cseq, via;
1504         unsigned int maxfwd_len;
1505         int tbracket, fbracket;
1506         str fromtag = STR_NULL;
1507         str loc_tag = STR_NULL;
1508
1509         if (!method || !dialog) {
1510                 LM_ERR("invalid parameter value\n");
1511                 return 0;
1512         }
1513
1514         if (dialog->id.loc_tag.len<=0) {
1515                 /* From Tag is mandatory in RFC3261 - generate one if not provided */
1516                 generate_fromtag(&fromtag, &dialog->id.call_id);
1517                 loc_tag = dialog->id.loc_tag;
1518                 dialog->id.loc_tag = fromtag;
1519         }
1520         if (print_content_length(&content_length, body) < 0) {
1521                 LM_ERR("error while printing content-length\n");
1522                 return 0;
1523         }
1524         if (print_cseq_num(&cseq, dialog) < 0) {
1525                 LM_ERR("error while printing CSeq number\n");
1526                 return 0;
1527         }
1528
1529         if(headers==NULL || headers->len<15
1530                         || _strnstr(headers->s, "Max-Forwards:", headers->len)==NULL) {
1531                 maxfwd_len = MAXFWD_HEADER_LEN;
1532         } else {
1533                 maxfwd_len = 0;
1534         }
1535
1536         *len = method->len + 1 + dialog->hooks.request_uri->len + 1
1537                 + SIP_VERSION_LEN + CRLF_LEN;
1538
1539         if (assemble_via(&via, t, dst, branch) < 0) {
1540                 LM_ERR("error while assembling Via\n");
1541                 return 0;
1542         }
1543         *len += via.len;
1544
1545         if((p=q_memrchr(dialog->rem_uri.s, '>', dialog->rem_uri.len))!=NULL) {
1546                 if((p==dialog->rem_uri.s + dialog->rem_uri.len - 1)
1547                                 || *(p+1)==';') {
1548                         tbracket = 0;
1549                 } else {
1550                         tbracket = 1;
1551                 }
1552         } else {
1553                 tbracket = 1;
1554         }
1555         if((p=q_memrchr(dialog->loc_uri.s, '>', dialog->loc_uri.len))!=NULL) {
1556                 if((p==dialog->loc_uri.s + dialog->loc_uri.len - 1)
1557                                 || *(p+1)==';') {
1558                         fbracket = 0;
1559                 } else {
1560                         fbracket = 1;
1561                 }
1562         } else {
1563                 fbracket = 1;
1564         }
1565
1566         *len += TO_LEN + dialog->rem_uri.len
1567                 + (dialog->id.rem_tag.len ? (TOTAG_LEN + dialog->id.rem_tag.len) : 0)
1568                 + CRLF_LEN;    /* To */
1569         if(tbracket) *len += 2; /* To-URI < > */
1570         *len += FROM_LEN + dialog->loc_uri.len
1571                 + (dialog->id.loc_tag.len ? (FROMTAG_LEN + dialog->id.loc_tag.len) : 0)
1572                 + CRLF_LEN;  /* From */
1573         if(fbracket) *len += 2; /* From-URI < > */
1574         *len += CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;   /* Call-ID */
1575         *len += CSEQ_LEN + cseq.len + 1 + method->len + CRLF_LEN; /* CSeq */
1576         *len += calculate_routeset_length(dialog);                /* Route set */
1577         *len += maxfwd_len;                                       /* Max-forwards */
1578         *len += CONTENT_LENGTH_LEN + content_length.len
1579                                                                                         + CRLF_LEN; /* Content-Length */
1580         *len += ((server_signature && user_agent_hdr.len>0)
1581                                                 ? (user_agent_hdr.len + CRLF_LEN) : 0); /* Signature */
1582         if(headers && headers->len>2) {
1583                 /* Additional headers */
1584                 *len += headers->len;
1585                 /* End of header if missing */
1586                 if(headers->s[headers->len - 1] != '\n')
1587                         *len += CRLF_LEN;
1588         }
1589         *len += (body ? body->len : 0);                         /* Message body */
1590         *len += CRLF_LEN;                                       /* End of Header */
1591
1592         buf = shm_malloc(*len + 1);
1593         if (!buf) {
1594                 LM_ERR("no more shared memory (%d)\n", *len);
1595                 goto error;
1596         }
1597
1598         w = buf;
1599
1600         w = print_request_uri(w, method, dialog, t, branch);  /* Request-URI */
1601         memapp(w, via.s, via.len);                            /* Top-most Via */
1602         w = print_to(w, dialog, t, tbracket);                 /* To */
1603         w = print_from(w, dialog, t, fbracket);               /* From */
1604         if(fromtag.len>0) {
1605                 dialog->id.loc_tag = loc_tag;
1606         }
1607         w = print_cseq(w, &cseq, method, t);                  /* CSeq */
1608         w = print_callid(w, dialog, t);                       /* Call-ID */
1609         w = print_routeset(w, dialog);                        /* Route set */
1610
1611         if(maxfwd_len>0)
1612                 memapp(w, MAXFWD_HEADER, MAXFWD_HEADER_LEN);      /* Max-forwards */
1613
1614         /* Content-Length */
1615         memapp(w, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
1616         memapp(w, content_length.s, content_length.len);
1617         memapp(w, CRLF, CRLF_LEN);
1618
1619         /* Server signature */
1620         if (server_signature && user_agent_hdr.len>0) {
1621                 memapp(w, user_agent_hdr.s, user_agent_hdr.len);
1622                 memapp(w, CRLF, CRLF_LEN);
1623         }
1624         if(headers && headers->len>2) {
1625                 memapp(w, headers->s, headers->len);
1626                 if(headers->s[headers->len - 1] != '\n')
1627                         memapp(w, CRLF, CRLF_LEN);
1628         }
1629         memapp(w, CRLF, CRLF_LEN);
1630         if (body) memapp(w, body->s, body->len);
1631
1632 #ifdef EXTRA_DEBUG
1633         assert(w-buf == *len);
1634 #endif
1635
1636         pkg_free(via.s);
1637         return buf;
1638
1639 error:
1640         pkg_free(via.s);
1641         return 0;
1642 }
1643
1644
1645 int t_calc_branch(struct cell *t,
1646         int b, char *branch, int *branch_len)
1647 {
1648         return branch_builder( t->hash_index,
1649                         0, t->md5,
1650                         b, branch, branch_len );
1651 }
1652
1653 /**
1654  * build CANCEL from UAC side
1655  */
1656 char *build_uac_cancel(str *headers,str *body,struct cell *cancelledT,
1657                 unsigned int branch, unsigned int *len, struct dest_info* dst)
1658 {
1659         char *cancel_buf, *p;
1660         char branch_buf[MAX_BRANCH_PARAM_LEN];
1661         str branch_str;
1662         struct hostport hp;
1663         str content_length, via;
1664
1665         LM_DBG("sing FROM=<%.*s>, TO=<%.*s>, CSEQ_N=<%.*s>\n",
1666                 cancelledT->from.len, cancelledT->from.s, cancelledT->to.len,
1667                 cancelledT->to.s, cancelledT->cseq_n.len, cancelledT->cseq_n.s);
1668
1669         branch_str.s=branch_buf;
1670         if (!t_calc_branch(cancelledT,  branch, branch_str.s, &branch_str.len )){
1671                 LM_ERR("failed to create branch !\n");
1672                 goto error;
1673         }
1674         set_hostport(&hp,0);
1675
1676         if (assemble_via(&via, cancelledT, dst, branch) < 0) {
1677                 LM_ERR("Error while assembling Via\n");
1678                 return 0;
1679         }
1680
1681         /* method, separators, version  */
1682         *len=CANCEL_LEN + 2 /* spaces */ +SIP_VERSION_LEN + CRLF_LEN;
1683         *len+=cancelledT->uac[branch].uri.len;
1684         /*via*/
1685         *len+= via.len;
1686         /*From*/
1687         *len+=cancelledT->from.len;
1688         /*To*/
1689         *len+=cancelledT->to.len;
1690         /*CallId*/
1691         *len+=cancelledT->callid.len;
1692         /*CSeq*/
1693         *len+=cancelledT->cseq_n.len+1+CANCEL_LEN+CRLF_LEN;
1694         /* User Agent */
1695         if (server_signature) {
1696                 *len += USER_AGENT_LEN + CRLF_LEN;
1697         }
1698         /* Content Length  */
1699         if (print_content_length(&content_length, body) < 0) {
1700                 LM_ERR("failed to print content-length\n");
1701                 return 0;
1702         }
1703         /* Content-Length */
1704         *len += (body ? (CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN) : 0);
1705         /*Additional headers*/
1706         *len += (headers ? headers->len : 0);
1707         /*EoM*/
1708         *len+= CRLF_LEN;
1709         /* Message body */
1710         *len += (body ? body->len : 0);
1711
1712         cancel_buf=shm_malloc( *len+1 );
1713         if (!cancel_buf)
1714         {
1715                 LM_ERR("no more share memory\n");
1716                 goto error01;
1717         }
1718         p = cancel_buf;
1719
1720         memapp( p, CANCEL, CANCEL_LEN );
1721
1722         *(p++) = ' ';
1723         memapp( p, cancelledT->uac[branch].uri.s,
1724                 cancelledT->uac[branch].uri.len);
1725         memapp( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );
1726
1727         /* insert our via */
1728         memapp(p,via.s,via.len);
1729
1730         /*other headers*/
1731         memapp( p, cancelledT->from.s, cancelledT->from.len );
1732         memapp( p, cancelledT->callid.s, cancelledT->callid.len );
1733         memapp( p, cancelledT->to.s, cancelledT->to.len );
1734
1735         memapp( p, cancelledT->cseq_n.s, cancelledT->cseq_n.len );
1736         *(p++) = ' ';
1737         memapp( p, CANCEL, CANCEL_LEN );
1738         memapp( p, CRLF, CRLF_LEN );
1739
1740         /* User Agent header */
1741         if (server_signature) {
1742                 memapp(p,USER_AGENT CRLF, USER_AGENT_LEN+CRLF_LEN );
1743         }
1744         /* Content Length*/
1745         if (body) {
1746                 memapp(p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
1747                 memapp(p, content_length.s, content_length.len);
1748                 memapp(p, CRLF, CRLF_LEN);
1749         }
1750         if(headers && headers->len){
1751                 memapp(p,headers->s,headers->len);
1752         }
1753         /*EoM*/
1754         memapp(p,CRLF,CRLF_LEN);
1755         if(body && body->len){
1756                 memapp(p,body->s,body->len);
1757         }
1758         *p=0;
1759         pkg_free(via.s);
1760         return cancel_buf;
1761 error01:
1762         pkg_free(via.s);
1763 error:
1764         return NULL;
1765 }
1766