tm: remove old timer based transaction delete functionality, not active since 2007
[kamailio] / src / modules / tm / uac.c
1 /*
2  * simple UAC for things such as SUBSCRIBE or SMS gateway;
3  * no authentication and other UAC features -- just send
4  * a message, retransmit and await a reply; forking is not
5  * supported during client generation, in all other places
6  * it is -- adding it should be simple
7  *
8  * Copyright (C) 2001-2003 FhG Fokus
9  *
10  * This file is part of Kamailio, a free SIP server.
11  *
12  * Kamailio is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version
16  *
17  * Kamailio is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  */
27
28 #include <string.h>
29 #include "../../core/mem/shm_mem.h"
30 #include "../../core/dprint.h"
31 #include "../../core/globals.h"
32 #include "../../core/md5.h"
33 #include "../../core/crc.h"
34 #include "../../core/ip_addr.h"
35 #include "../../core/dset.h"
36 #include "../../core/socket_info.h"
37 #include "../../core/compiler_opt.h"
38 #include "../../core/parser/parse_cseq.h"
39 #include "../../core/rand/kam_rand.h"
40 #include "config.h"
41 #include "ut.h"
42 #include "h_table.h"
43 #include "t_hooks.h"
44 #include "t_funcs.h"
45 #include "t_msgbuilder.h"
46 #include "callid.h"
47 #include "uac.h"
48 #include "t_stats.h"
49 #ifdef USE_DNS_FAILOVER
50 #include "../../core/dns_cache.h"
51 #include "../../core/cfg_core.h" /* cfg_get(core, core_cfg, use_dns_failover) */
52 #endif
53 #ifdef WITH_EVENT_LOCAL_REQUEST
54 #include "../../core/data_lump.h"
55 #include "../../core/receive.h"
56 #include "../../core/route.h"
57 #include "../../core/action.h"
58 #include "../../core/onsend.h"
59 #include "t_lookup.h"
60 #include "t_fwd.h"
61 #endif
62
63 #define FROM_TAG_LEN (MD5_LEN + 1 /* - */ + CRC16_LEN) /* length of FROM tags */
64
65 #ifdef WITH_EVENT_LOCAL_REQUEST
66 /* where to go for the local request route ("tm:local-request") */
67 int goto_on_local_req=-1; /* default disabled */
68 #endif /* WITH_EVEN_LOCAL_REQuEST */
69
70 static char from_tag[FROM_TAG_LEN + 1];
71
72 extern str tm_event_callback;
73 /*
74  * Initialize UAC
75  */
76 int uac_init(void)
77 {
78         str src[3];
79         struct socket_info *si;
80
81         if (KAM_RAND_MAX < TABLE_ENTRIES) {
82                 LM_WARN("uac does not spread across the whole hash table\n");
83         }
84         /* on tcp/tls bind_address is 0 so try to get the first address we listen
85          * on no matter the protocol */
86         si=bind_address?bind_address:get_first_socket();
87         if (si==0){
88                 LM_CRIT("BUG - null socket list\n");
89                 return -1;
90         }
91
92         /* calculate the initial From tag */
93         src[0].s = "Long live " NAME " server";
94         src[0].len = strlen(src[0].s);
95         src[1].s = si->address_str.s;
96         src[1].len = strlen(src[1].s);
97         src[2].s = si->port_no_str.s;
98         src[2].len = strlen(src[2].s);
99
100         MD5StringArray(from_tag, src, 3);
101         from_tag[MD5_LEN] = '-';
102         return 1;
103 }
104
105
106 /*
107  * Generate a From tag
108  */
109 void generate_fromtag(str* tag, str* callid)
110 {
111              /* calculate from tag from callid */
112         crcitt_string_array(&from_tag[MD5_LEN + 1], callid, 1);
113         tag->s = from_tag;
114         tag->len = FROM_TAG_LEN;
115 }
116
117
118 /*
119  * Check value of parameters
120  */
121 static inline int check_params(uac_req_t *uac_r, str* to, str* from)
122 {
123         if (!uac_r || !uac_r->method || !to || !from) {
124                 LM_ERR("Invalid parameter value\n");
125                 return -1;
126         }
127
128         if (!uac_r->method->s || !uac_r->method->len) {
129                 LM_ERR("Invalid request method\n");
130                 return -2;
131         }
132
133         if (!to->s || !to->len) {
134                 LM_ERR("Invalid To URI\n");
135                 return -4;
136         }
137
138         if (!from->s || !from->len) {
139                 LM_ERR("Invalid From URI\n");
140                 return -5;
141         }
142         return 0;
143 }
144
145 static inline unsigned int dlg2hash( dlg_t* dlg )
146 {
147         str cseq_nr;
148         unsigned int hashid;
149
150         cseq_nr.s=int2str(dlg->loc_seq.value, &cseq_nr.len);
151         hashid=hash(dlg->id.call_id, cseq_nr);
152         LM_DBG("hashid %d\n", hashid);
153         return hashid;
154 }
155
156 /**
157  * refresh hdr shortcuts inside new buffer
158  */
159 int uac_refresh_hdr_shortcuts(tm_cell_t *tcell, char *buf, int buf_len)
160 {
161         sip_msg_t lreq;
162         struct cseq_body *cs;
163
164         if(likely(build_sip_msg_from_buf(&lreq, buf, buf_len, inc_msg_no())<0)) {
165                 LM_ERR("failed to parse msg buffer\n");
166                 return -1;
167         }
168         if(parse_headers(&lreq,HDR_CSEQ_F|HDR_CALLID_F|HDR_FROM_F|HDR_TO_F,0)<0) {
169                 LM_ERR("failed to parse headers in new message\n");
170                 goto error;
171         }
172         tcell->from.s = lreq.from->name.s;
173         tcell->from.len = lreq.from->len;
174         tcell->to.s = lreq.to->name.s;
175         tcell->to.len = lreq.to->len;
176         tcell->callid.s = lreq.callid->name.s;
177         tcell->callid.len = lreq.callid->len;
178
179         cs = get_cseq(&lreq);
180         tcell->cseq_n.s = lreq.cseq->name.s;
181         tcell->cseq_n.len = (int)(cs->number.s + cs->number.len - lreq.cseq->name.s);
182
183         LM_DBG("cseq: [%.*s]\n", tcell->cseq_n.len, tcell->cseq_n.s);
184         lreq.buf=0; /* covers the obsolete DYN_BUF */
185         free_sip_msg(&lreq);
186         return 0;
187
188 error:
189         lreq.buf=0; /* covers the obsolete DYN_BUF */
190         free_sip_msg(&lreq);
191         return -1;
192 }
193
194
195 #if defined(USE_DNS_FAILOVER) || defined(WITH_EVENT_LOCAL_REQUEST)
196 static inline int t_build_msg_from_buf(
197                         struct sip_msg *msg, char *buf, int buf_len,
198                         uac_req_t *uac_r, struct dest_info *dst)
199 {
200         if (unlikely(build_sip_msg_from_buf(msg, buf, buf_len, inc_msg_no()) != 0)) {
201                 return -1;
202         }
203         msg->force_send_socket = uac_r->dialog->send_sock;
204         msg->rcv.proto = dst->send_sock->proto;
205         msg->rcv.src_ip = dst->send_sock->address;
206         su2ip_addr(&msg->rcv.dst_ip, &dst->to);
207         msg->rcv.src_port = dst->send_sock->port_no;
208         msg->rcv.dst_port = su_getport(&dst->to);
209         msg->rcv.src_su=dst->send_sock->su;
210         msg->rcv.bind_address=dst->send_sock;
211 #ifdef USE_COMP
212         msg->rcv.comp=dst->comp;
213 #endif /* USE_COMP */
214
215         return 0;
216 }
217
218 #ifdef WITH_EVENT_LOCAL_REQUEST
219 static inline int t_run_local_req(
220                 char **buf, int *buf_len,
221                 uac_req_t *uac_r,
222                 struct cell *new_cell, struct retr_buf *request)
223 {
224         struct sip_msg lreq = {0};
225         struct onsend_info onsnd_info;
226         tm_xlinks_t backup_xd;
227         int sflag_bk;
228         char *buf1;
229         int buf_len1;
230         int backup_route_type;
231         struct cell *backup_t;
232         int backup_branch;
233         msg_ctx_id_t backup_ctxid;
234         int refresh_shortcuts = 0;
235         sr_kemi_eng_t *keng = NULL;
236         str evname = str_init("tm:local-request");
237
238         LM_DBG("executing event_route[tm:local-request]\n");
239         if (unlikely(t_build_msg_from_buf(&lreq, *buf, *buf_len, uac_r, &request->dst))) {
240                 return -1;
241         }
242         if (unlikely(set_dst_uri(&lreq, uac_r->dialog->hooks.next_hop))) {
243                 LM_ERR("failed to set dst_uri\n");
244                 free_sip_msg(&lreq);
245                 return -1;
246         }
247         sflag_bk = getsflags();
248         tm_xdata_swap(new_cell, &backup_xd, 0);
249
250         onsnd_info.to=&request->dst.to;
251         onsnd_info.send_sock=request->dst.send_sock;
252         onsnd_info.buf=*buf;
253         onsnd_info.len=*buf_len;
254         p_onsend=&onsnd_info;
255
256         /* run the route */
257         backup_route_type = get_route_type();
258         set_route_type(LOCAL_ROUTE);
259         /* set T to the current transaction */
260         backup_t=get_t();
261         backup_branch=get_t_branch();
262         backup_ctxid.msgid=tm_global_ctx_id.msgid;
263         backup_ctxid.pid=tm_global_ctx_id.pid;
264         /* fake transaction and message id */
265         tm_global_ctx_id.msgid=lreq.id;
266         tm_global_ctx_id.pid=lreq.pid;
267         set_t(new_cell, T_BR_UNDEFINED);
268         if(goto_on_local_req>=0) {
269                 run_top_route(event_rt.rlist[goto_on_local_req], &lreq, 0);
270         } else {
271                 keng = sr_kemi_eng_get();
272                 if(keng==NULL) {
273                         LM_WARN("event callback (%s) set, but no cfg engine\n",
274                                         tm_event_callback.s);
275                 } else {
276                         if(sr_kemi_route(keng, &lreq, EVENT_ROUTE,
277                                                 &tm_event_callback, &evname)<0) {
278                                 LM_ERR("error running event route kemi callback\n");
279                         }
280                 }
281         }
282         /* restore original environment */
283         set_t(backup_t, backup_branch);
284         tm_global_ctx_id.msgid=backup_ctxid.msgid;
285         tm_global_ctx_id.pid=backup_ctxid.pid;
286         set_route_type( backup_route_type );
287         p_onsend=0;
288
289         /* restore original environment */
290         tm_xdata_swap(new_cell, &backup_xd, 1);
291         setsflagsval(sflag_bk);
292
293         /* rebuild the new message content */
294         if(lreq.force_send_socket != uac_r->dialog->send_sock) {
295                 LM_DBG("Send socket updated to: %.*s",
296                                 lreq.force_send_socket->address_str.len,
297                                 lreq.force_send_socket->address_str.s);
298
299                 /* rebuild local Via - remove previous value
300                         * and add the one for the new send socket */
301                 if (!del_lump(&lreq, lreq.h_via1->name.s - lreq.buf,
302                                         lreq.h_via1->len, 0)) {
303                         LM_ERR("Failed to remove previous local Via\n");
304                         /* attempt a normal update to give it a chance */
305                         goto normal_update;
306                 }
307
308                 /* reuse same branch value from previous local Via */
309                 memcpy(lreq.add_to_branch_s, lreq.via1->branch->value.s,
310                                 lreq.via1->branch->value.len);
311                 lreq.add_to_branch_len = lreq.via1->branch->value.len;
312
313                 /* update also info about new destination and send sock */
314                 uac_r->dialog->send_sock=lreq.force_send_socket;
315                 request->dst.send_sock = lreq.force_send_socket;
316                 request->dst.proto = lreq.force_send_socket->proto;
317
318                 LM_DBG("apply new updates with Via to sip msg\n");
319                 buf1 = build_req_buf_from_sip_req(&lreq,
320                                 (unsigned int*)&buf_len1, &request->dst, BUILD_IN_SHM);
321                 if (likely(buf1)){
322                         shm_free(*buf);
323                         *buf = buf1;
324                         *buf_len = buf_len1;
325                         /* a possible change of the method is not handled! */
326                         refresh_shortcuts = 1;
327                 }
328
329         } else {
330 normal_update:
331                 if (unlikely(lreq.add_rm || lreq.body_lumps || lreq.new_uri.s)) {
332                         LM_DBG("apply new updates without Via to sip msg\n");
333                         buf1 = build_req_buf_from_sip_req(&lreq,
334                                         (unsigned int*)&buf_len1,
335                                         &request->dst, BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE|
336                                         BUILD_IN_SHM);
337                         if (likely(buf1)){
338                                 shm_free(*buf);
339                                 *buf = buf1;
340                                 *buf_len = buf_len1;
341                                 /* a possible change of the method is not handled! */
342                                 refresh_shortcuts = 1;
343                         }
344                 }
345         }
346
347         /* clean local msg structure */
348         if (unlikely(lreq.new_uri.s))
349         {
350                 pkg_free(lreq.new_uri.s);
351                 lreq.new_uri.s=0;
352                 lreq.new_uri.len=0;
353         }
354         if (unlikely(lreq.dst_uri.s))
355         {
356                 pkg_free(lreq.dst_uri.s);
357                 lreq.dst_uri.s=0;
358                 lreq.dst_uri.len=0;
359         }
360         lreq.buf=0; /* covers the obsolete DYN_BUF */
361         free_sip_msg(&lreq);
362         return refresh_shortcuts;
363 }
364 #endif /* WITH_EVENT_LOCAL_REQUEST */
365 #endif /* defined(USE_DNS_FAILOVER) || defined(WITH_EVENT_LOCAL_REQUEST) */
366
367
368 /* WARNING: - dst_cell contains the created cell, but it is un-referenced
369  *            (before using it make sure you REF() it first)
370  *          - if  ACK (method==ACK), a cell will be created but it will not
371  *            be added in the hash table (should be either deleted by the
372  *            caller)
373  */
374 static inline int t_uac_prepare(uac_req_t *uac_r,
375                 struct retr_buf **dst_req,
376                 struct cell **dst_cell)
377 {
378         struct dest_info dst;
379         struct cell *new_cell;
380         struct retr_buf *request;
381         char *buf;
382         int buf_len, ret;
383         unsigned int hi;
384         int is_ack;
385         ticks_t lifetime;
386         long nhtype;
387         snd_flags_t snd_flags;
388         tm_xlinks_t backup_xd;
389         tm_xdata_t local_xd;
390         int refresh_shortcuts = 0;
391         int sip_msg_len;
392 #ifdef USE_DNS_FAILOVER
393         static struct sip_msg lreq;
394 #endif /* USE_DNS_FAILOVER */
395
396         ret=-1;
397         hi=0; /* make gcc happy */
398         /*if (dst_req) *dst_req = NULL;*/
399         is_ack = (((uac_r->method->len == 3) && (memcmp("ACK",
400                                                 uac_r->method->s, 3)==0)) ? 1 : 0);
401
402         /*** added by dcm
403          * - needed by external ua to send a request within a dlg
404          */
405         if ((nhtype = w_calculate_hooks(uac_r->dialog)) < 0)
406                 /* if err's returned, the message is incorrect */
407                 goto error3;
408
409         if (!uac_r->dialog->loc_seq.is_set) {
410                 /* this is the first request in the dialog,
411                 set cseq to default value now - Miklos */
412                 uac_r->dialog->loc_seq.value = DEFAULT_CSEQ;
413                 uac_r->dialog->loc_seq.is_set = 1;
414         }
415
416         /* build cell sets X/AVP lists to new transaction structure
417          * => backup in a tmp struct and restore afterwards */
418         memset(&local_xd, 0, sizeof(tm_xdata_t));
419         tm_xdata_replace(&local_xd, &backup_xd);
420         new_cell = build_cell(0);
421         tm_xdata_replace(0, &backup_xd);
422
423         if (!new_cell) {
424                 ret=E_OUT_OF_MEM;
425                 LM_ERR("short of cell shmem\n");
426                 goto error3;
427         }
428
429         LM_DBG("next_hop=<%.*s>\n",uac_r->dialog->hooks.next_hop->len,
430                         uac_r->dialog->hooks.next_hop->s);
431         /* new message => take the dialog send_socket if set, or the default
432           send_socket if not*/
433         SND_FLAGS_INIT(&snd_flags);
434
435         if (uac_r->dialog->send_sock != NULL)
436         {
437                 snd_flags.f |= SND_F_FORCE_SOCKET;
438         }
439
440 #ifdef USE_DNS_FAILOVER
441         if ((uri2dst2(cfg_get(core, core_cfg, use_dns_failover) ? &new_cell->uac[0].dns_h : 0,
442                         &dst, uac_r->dialog->send_sock, snd_flags,
443                         uac_r->dialog->hooks.next_hop, PROTO_NONE)==0)
444                                 || (dst.send_sock==0)){
445 #else /* USE_DNS_FAILOVER */
446         if ((uri2dst2(&dst, uac_r->dialog->send_sock, snd_flags,
447                                         uac_r->dialog->hooks.next_hop, PROTO_NONE)==0) ||
448                         (dst.send_sock==0)){
449 #endif /* USE_DNS_FAILOVER */
450                 ser_error = E_NO_SOCKET;
451                 ret=ser_error;
452                 LM_ERR("no socket found\n");
453                 goto error2;
454         }
455
456         if (uac_r->method->len==INVITE_LEN && memcmp(uac_r->method->s, INVITE, INVITE_LEN)==0){
457                 new_cell->flags |= T_IS_INVITE_FLAG;
458                 new_cell->flags|=T_AUTO_INV_100 &
459                                 (!cfg_get(tm, tm_cfg, tm_auto_inv_100) -1);
460 #ifdef WITH_AS_SUPPORT
461                 if (uac_r->cb_flags & TMCB_DONT_ACK)
462                         new_cell->flags |= T_NO_AUTO_ACK;
463 #endif
464                 lifetime=cfg_get(tm, tm_cfg, tm_max_inv_lifetime);
465         }else
466                 lifetime=cfg_get(tm, tm_cfg, tm_max_noninv_lifetime);
467         new_cell->flags |= T_IS_LOCAL_FLAG;
468         /* init timers hack, new_cell->fr_timer and new_cell->fr_inv_timer
469          * must be set, or else the fr will happen immediately
470          * we can't call init_new_t() because we don't have a sip msg
471          * => we'll ignore t_set_fr() or avp timer value and will use directly the
472          * module params fr_inv_timer and fr_timer -- andrei */
473         new_cell->fr_timeout=cfg_get(tm, tm_cfg, fr_timeout);
474         new_cell->fr_inv_timeout=cfg_get(tm, tm_cfg, fr_inv_timeout);
475         new_cell->end_of_life=get_ticks_raw()+lifetime;
476 #ifdef TM_DIFF_RT_TIMEOUT
477         /* same as above for retransmission intervals */
478         new_cell->rt_t1_timeout_ms = cfg_get(tm, tm_cfg, rt_t1_timeout_ms);
479         new_cell->rt_t2_timeout_ms = cfg_get(tm, tm_cfg, rt_t2_timeout_ms);
480 #endif
481
482         set_kr(REQ_FWDED);
483
484         request = &new_cell->uac[0].request;
485         request->dst = dst;
486         request->flags |= nhtype;
487
488 #ifdef SO_REUSEPORT
489         if (cfg_get(tcp, tcp_cfg, reuse_port) && 
490                         uac_r->ssock!=NULL && uac_r->ssock->len>0 &&
491                         request->dst.send_sock->proto == PROTO_TCP) {
492                 request->dst.send_flags.f |= SND_F_FORCE_SOCKET;
493         }
494 #endif
495
496         if (!is_ack) {
497                 INIT_REF(new_cell, 1); /* ref'ed only from the hash */
498                 hi=dlg2hash(uac_r->dialog);
499                 LOCK_HASH(hi);
500                 insert_into_hash_table_unsafe(new_cell, hi);
501                 UNLOCK_HASH(hi);
502         }
503
504         buf = build_uac_req(uac_r->method, uac_r->headers, uac_r->body, uac_r->dialog, 0, new_cell,
505                 &buf_len, &dst);
506         if (!buf) {
507                 LM_ERR("Error while building message\n");
508                 ret=E_OUT_OF_MEM;
509                 goto error1;
510         }
511
512 #ifdef WITH_EVENT_LOCAL_REQUEST
513         if (unlikely(goto_on_local_req>=0 || tm_event_callback.len>0)) {
514                 refresh_shortcuts = t_run_local_req(&buf, &buf_len, uac_r, new_cell, request);
515         }
516 #endif
517
518 #ifdef USE_DNS_FAILOVER
519         /* Set the outgoing message as UAS, so the failover code has something to work with */
520         if(cfg_get(core, core_cfg, use_dns_failover)) {
521                 if(likely(t_build_msg_from_buf(&lreq, buf, buf_len, uac_r, &dst) == 0)) {
522                         if (parse_headers(&lreq, HDR_EOH_F, 0) == -1) {
523                                 LM_ERR("failed to parse headers on uas for failover\n");
524                         } else {
525                                 new_cell->uas.request = sip_msg_cloner(&lreq, &sip_msg_len);
526                                 lreq.buf=0; /* covers the obsolete DYN_BUF */
527                                 free_sip_msg(&lreq);
528                                 if (!new_cell->uas.request) {
529                                         LM_ERR("no more shmem\n");
530                                         goto error1;
531                                 }
532                                 new_cell->uas.end_request=((char*)new_cell->uas.request)+sip_msg_len;
533                         }
534                 } else {
535                         LM_WARN("failed to build uas for failover\n");
536                 }
537         }
538 #endif /* USE_DNS_FAILOVER */
539
540         new_cell->uac[0].on_reply = new_cell->on_reply;
541         new_cell->uac[0].on_failure = new_cell->on_failure;
542
543         new_cell->method.s = buf;
544         new_cell->method.len = uac_r->method->len;
545
546         request->buffer = buf;
547         request->buffer_len = buf_len;
548         if(unlikely(refresh_shortcuts==1)) {
549                 if(uac_refresh_hdr_shortcuts(new_cell, buf, buf_len)<0) {
550                         LM_ERR("failed to refresh header shortcuts\n");
551                         goto error1;
552                 }
553         }
554         new_cell->nr_of_outgoings++;
555
556         /* Register the callbacks after everything is successful and nothing can fail.
557         Otherwise the callback parameter would be freed twise, once from TMCB_DESTROY,
558         and again because of the negative return code. */
559         if(uac_r->cb && insert_tmcb(&(new_cell->tmcb_hl), uac_r->cb_flags,
560                                                                 *(uac_r->cb), uac_r->cbp, NULL)!=1){
561                 ret=E_OUT_OF_MEM;
562                 LM_ERR("short of tmcb shmem\n");
563                 goto error1;
564         }
565         if (has_local_reqin_tmcbs())
566                         run_local_reqin_callbacks(new_cell, 0, 0);
567 #ifdef DIALOG_CALLBACKS
568         run_trans_dlg_callbacks(uac_r->dialog, new_cell, request);
569 #endif /* DIALOG_CALLBACKS */
570         if (dst_req) *dst_req = request;
571         if (dst_cell) *dst_cell = new_cell;
572         else if(is_ack && dst_req==0){
573                 free_cell(new_cell);
574         }
575
576         return 1;
577
578  error1:
579         if (!is_ack) {
580                 LOCK_HASH(hi);
581                 remove_from_hash_table_unsafe(new_cell);
582                 UNLOCK_HASH(hi);
583         }
584
585 error2:
586         if (is_ack) {
587                 free_cell(new_cell);
588         } else {
589                 if((new_cell->next_c == 0 && new_cell->prev_c == 0)
590                                 || (atomic_get_int(&new_cell->ref_count)==0)) {
591                         free_cell(new_cell);
592                 } else {
593                         UNREF_FREE(new_cell, 0);
594                 }
595         }
596 error3:
597         return ret;
598 }
599
600 /*
601  * Prepare a message within a dialog
602  */
603 int prepare_req_within(uac_req_t *uac_r,
604                 struct retr_buf **dst_req)
605 {
606         if (!uac_r || !uac_r->method || !uac_r->dialog) {
607                 LM_ERR("Invalid parameter value\n");
608                 goto err;
609         }
610
611         if (uac_r->dialog->state != DLG_CONFIRMED) {
612                 LM_ERR("Dialog is not confirmed yet\n");
613                 goto err;
614         }
615
616         if ((uac_r->method->len == 3) && (!memcmp("ACK", uac_r->method->s, 3))) goto send;
617         if ((uac_r->method->len == 6) && (!memcmp("CANCEL", uac_r->method->s, 6))) goto send;
618         uac_r->dialog->loc_seq.value++; /* Increment CSeq */
619  send:
620         return t_uac_prepare(uac_r, dst_req, 0);
621
622  err:
623         /* if (cbp) shm_free(cbp); */
624         /* !! never free cbp here because if t_uac_prepare fails, cbp is not freed
625          * and thus caller has no chance to discover if it is freed or not !! */
626         return -1;
627 }
628
629 static inline int send_prepared_request_impl(struct retr_buf *request, int retransmit, int branch)
630 {
631         struct cell *t;
632         struct sip_msg *p_msg;
633         struct ua_client *uac;
634         struct ip_addr ip; /* logging */
635         int ret;
636
637         t = request->my_T;
638         uac = &t->uac[branch];
639         p_msg = t->uas.request;
640
641         if (SEND_BUFFER(request) == -1) {
642                 LM_ERR("Attempt to send to precreated request failed\n");
643         }
644         else if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_SENT)))
645                 /* we don't know the method here */
646                 run_trans_callbacks_with_buf(TMCB_REQUEST_SENT, &uac->request, 0, 0,
647                         TMCB_LOCAL_F);
648
649         su2ip_addr(&ip, &uac->request.dst.to);
650         LM_DBG("uac: %p  branch: %d  to %s:%d\n",
651                         uac, branch, ip_addr2a(&ip), su_getport(&uac->request.dst.to));
652
653         if (run_onsend(p_msg, &uac->request.dst, uac->request.buffer,
654                         uac->request.buffer_len)==0){
655                 uac->last_received=408;
656                 su2ip_addr(&ip, &uac->request.dst.to);
657                 LM_DBG("onsend_route dropped msg. to %s:%d (%d)\n",
658                                                 ip_addr2a(&ip), su_getport(&uac->request.dst.to),
659                                                 uac->request.dst.proto);
660 #ifdef USE_DNS_FAILOVER
661                 /* if the destination resolves to more ips, add another
662                         *  branch/uac */
663                 ret = add_uac_dns_fallback(t, p_msg, uac, retransmit);
664                 if (ret > 0) {
665                         su2ip_addr(&ip, &uac->request.dst.to);
666                         LM_DBG("send on branch %d failed "
667                                         "(onsend_route), trying another ip %s:%d (%d)\n",
668                                         branch, ip_addr2a(&ip),
669                                         su_getport(&uac->request.dst.to),
670                                         uac->request.dst.proto);
671                         /* success, return new branch */
672                         return ret;
673                 }
674 #endif /* USE_DNS_FAILOVER*/
675                 return -1;
676         }
677
678         if (retransmit && (start_retr(&uac->request)!=0))
679                 LM_CRIT("BUG: failed to start retr. for %p\n", &uac->request);
680         return 0;
681 }
682
683 void send_prepared_request(struct retr_buf *request)
684 {
685         send_prepared_request_impl(request, 1 /* retransmit */, 0);
686 }
687
688 /*
689  * Send a request using data from the dialog structure
690  */
691 int t_uac(uac_req_t *uac_r)
692 {
693         return t_uac_with_ids(uac_r, NULL, NULL);
694 }
695
696 /*
697  * Send a request using data from the dialog structure
698  * ret_index and ret_label will identify the new cell
699  */
700 int t_uac_with_ids(uac_req_t *uac_r,
701         unsigned int *ret_index, unsigned int *ret_label)
702 {
703         struct retr_buf *request;
704         struct cell *cell;
705         int ret;
706         int is_ack;
707         int branch_ret;
708         int i;
709         branch_bm_t added_branches = 1;
710
711         ret = t_uac_prepare(uac_r, &request, &cell);
712         if (ret < 0) return ret;
713         is_ack = (uac_r->method->len == 3) && (memcmp("ACK", uac_r->method->s, 3)==0) ? 1 : 0;
714
715         /* equivalent loop to the one in t_forward_nonack */
716         for (i=0; i<cell->nr_of_outgoings; i++) {
717                 if (added_branches & (1<<i)) {
718                         branch_ret=send_prepared_request_impl(request, !is_ack /* retransmit */, i);
719                         if (branch_ret>=0){ /* some kind of success */
720                                 if (branch_ret>i) {
721                                         /* new branch added */
722                                         added_branches |= 1<<branch_ret;
723                                 }
724                         }
725                 }
726         }
727
728         if (is_ack) {
729                 free_cell(cell);
730                 if (ret_index && ret_label)
731                         *ret_index = *ret_label = 0;
732         } else {
733                 if (ret_index && ret_label) {
734                         *ret_index = cell->hash_index;
735                         *ret_label = cell->label;
736                 }
737         }
738         return ret;
739 }
740
741 #ifdef WITH_AS_SUPPORT
742 struct retr_buf *local_ack_rb(sip_msg_t *rpl_2xx, struct cell *trans,
743                                         unsigned int branch, str *hdrs, str *body)
744 {
745         struct retr_buf *lack;
746         unsigned int buf_len;
747         char *buffer;
748         struct dest_info dst;
749
750         buf_len = (unsigned)sizeof(struct retr_buf);
751         if (! (buffer = build_dlg_ack(rpl_2xx, trans, branch, hdrs, body,
752                         &buf_len, &dst))) {
753                 return 0;
754         } else {
755                 /* 'buffer' now points into a contiguous chunk of memory with enough
756                  * room to hold both the retr. buffer and the string raw buffer: it
757                  * points to the begining of the string buffer; we iterate back to get
758                  * the begining of the space for the retr. buffer. */
759                 lack = &((struct retr_buf *)buffer)[-1];
760                 lack->buffer = buffer;
761                 lack->buffer_len = buf_len;
762                 lack->dst = dst;
763         }
764
765         /* TODO: need next 2? */
766         lack->rbtype = TYPE_LOCAL_ACK;
767         lack->my_T = trans;
768
769         return lack;
770 }
771
772 void free_local_ack(struct retr_buf *lack)
773 {
774         shm_free(lack);
775 }
776
777 void free_local_ack_unsafe(struct retr_buf *lack)
778 {
779         shm_free_unsafe(lack);
780 }
781
782 /**
783  * @return:
784  *      0: success
785  *      -1: internal error
786  *      -2: insane call :)
787  */
788 int ack_local_uac(struct cell *trans, str *hdrs, str *body)
789 {
790         struct retr_buf *local_ack, *old_lack;
791         int ret;
792         struct tmcb_params onsend_params;
793
794         /* sanity checks */
795
796 #ifdef EXTRA_DEBUG
797         if (! trans) {
798                 LM_BUG("no transaction to ACK.\n");
799                 abort();
800         }
801 #endif
802
803 #define RET_INVALID \
804                 ret = -2; \
805                 goto fin
806
807         if (! is_local(trans)) {
808                 LM_ERR("trying to ACK non local transaction (T@%p).\n", trans);
809                 RET_INVALID;
810         }
811         if (! is_invite(trans)) {
812                 LM_ERR("trying to ACK non INVITE local transaction (T@%p).\n", trans);
813                 RET_INVALID;
814         }
815         if (! trans->uac[0].reply) {
816                 LM_ERR("trying to ACK un-completed INVITE transaction (T@%p).\n", trans);
817                 RET_INVALID;
818         }
819
820         if (! (trans->flags & T_NO_AUTO_ACK)) {
821                 LM_ERR("trying to ACK an auto-ACK transaction (T@%p).\n", trans);
822                 RET_INVALID;
823         }
824         if (trans->uac[0].local_ack) {
825                 LM_ERR("trying to rebuild ACK retransmission buffer (T@%p).\n", trans);
826                 RET_INVALID;
827         }
828
829         /* looks sane: build the retransmission buffer */
830
831         if (! (local_ack = local_ack_rb(trans->uac[0].reply, trans, /*branch*/0,
832                         hdrs, body))) {
833                 LM_ERR("failed to build ACK retransmission buffer\n");
834                 RET_INVALID;
835         } else {
836                 /* set the new buffer, but only if not already set (conc. invok.) */
837                 if ((old_lack = (struct retr_buf *)atomic_cmpxchg_long(
838                                 (void *)&trans->uac[0].local_ack, 0, (long)local_ack))) {
839                         /* buffer already set: deny current attempt */
840                         LM_ERR("concurrent ACKing for local INVITE detected (T@%p).\n",trans);
841                         free_local_ack(local_ack);
842                         RET_INVALID;
843                 }
844         }
845
846         if (msg_send(&local_ack->dst, local_ack->buffer, local_ack->buffer_len)<0){
847                 /* hopefully will succeed on next 2xx retransmission */
848                 LM_ERR("failed to send local ACK (T@%p).\n", trans);
849                 ret = -1;
850                 goto fin;
851         }
852         else {
853                 INIT_TMCB_ONSEND_PARAMS(onsend_params, 0, 0, &trans->uac[0].request,
854                                                                 &local_ack->dst,
855                                                                 local_ack->buffer, local_ack->buffer_len,
856                                                                 TMCB_LOCAL_F, 0 /* branch */, TYPE_LOCAL_ACK);
857                 run_trans_callbacks_off_params(TMCB_REQUEST_SENT, trans, &onsend_params);
858         }
859
860         ret = 0;
861 fin:
862         /* TODO: ugly! */
863         /* FIXME: the T had been obtain by t_lookup_ident()'ing for it, so, it is
864          * ref-counted. The t_unref() can not be used, as it requests a valid SIP
865          * message (all available might be the reply, but if AS goes wrong and
866          * tries to ACK before the final reply is received, we still have to
867          * lookup the T to find this out). */
868         UNREF( trans );
869         return ret;
870
871 #undef RET_INVALID
872 }
873 #endif /* WITH_AS_SUPPORT */
874
875
876 /*
877  * Send a message within a dialog
878  */
879 int req_within(uac_req_t *uac_r)
880 {
881         int ret;
882         char nbuf[MAX_URI_SIZE];
883 #define REQ_DST_URI_SIZE        80
884         char dbuf[REQ_DST_URI_SIZE];
885         str ouri = {0, 0};
886         str nuri = {0, 0};
887         str duri = {0, 0};
888
889         if (!uac_r || !uac_r->method || !uac_r->dialog) {
890                 LM_ERR("Invalid parameter value\n");
891                 goto err;
892         }
893
894         if(uac_r->ssock!=NULL && uac_r->ssock->len>0
895                         && uac_r->dialog->send_sock==NULL) {
896                 /* set local send socket */
897                 uac_r->dialog->send_sock = lookup_local_socket(uac_r->ssock);
898         }
899
900         /* handle alias parameter in uri
901          * - only if no dst uri and no route set - */
902         if(uac_r->dialog && uac_r->dialog->rem_target.len>0
903                         && uac_r->dialog->dst_uri.len==0
904                         && uac_r->dialog->route_set==NULL) {
905                 ouri = uac_r->dialog->rem_target;
906                 /*restore alias parameter*/
907                 nuri.s = nbuf;
908                 nuri.len = MAX_URI_SIZE;
909                 duri.s = dbuf;
910                 duri.len = REQ_DST_URI_SIZE;
911                 if(uri_restore_rcv_alias(&ouri, &nuri, &duri)<0) {
912                         nuri.len = 0;
913                         duri.len = 0;
914                 }
915                 if(nuri.len>0 && duri.len>0) {
916                         uac_r->dialog->rem_target = nuri;
917                         uac_r->dialog->dst_uri    = duri;
918                 } else {
919                         ouri.len = 0;
920                 }
921         }
922
923         if ((uac_r->method->len == 3) && (!memcmp("ACK", uac_r->method->s, 3))) goto send;
924         if ((uac_r->method->len == 6) && (!memcmp("CANCEL", uac_r->method->s, 6))) goto send;
925         uac_r->dialog->loc_seq.value++; /* Increment CSeq */
926  send:
927         ret = t_uac(uac_r);
928         if(ouri.len>0) {
929                 uac_r->dialog->rem_target = ouri;
930                 uac_r->dialog->dst_uri.s = 0;
931                 uac_r->dialog->dst_uri.len = 0;
932         }
933         return ret;
934
935  err:
936         /* callback parameter must be freed outside of tm module
937         if (cbp) shm_free(cbp); */
938         if(ouri.len>0) {
939                 uac_r->dialog->rem_target = ouri;
940                 uac_r->dialog->dst_uri.s = 0;
941                 uac_r->dialog->dst_uri.len = 0;
942         }
943         return -1;
944 }
945
946
947 /*
948  * Send an initial request that will start a dialog
949  * WARNING: writes uac_r->dialog
950  */
951 int req_outside(uac_req_t *uac_r, str* ruri, str* to, str* from, str *next_hop)
952 {
953         str callid, fromtag;
954
955         if (check_params(uac_r, to, from) < 0) goto err;
956
957         generate_callid(&callid);
958         generate_fromtag(&fromtag, &callid);
959
960         if (new_dlg_uac(&callid, &fromtag, DEFAULT_CSEQ, from, to, &uac_r->dialog) < 0) {
961                 LM_ERR("Error while creating new dialog\n");
962                 goto err;
963         }
964
965         if (ruri) {
966                 uac_r->dialog->rem_target.s = ruri->s;
967                 uac_r->dialog->rem_target.len = ruri->len;
968                 /* hooks will be set from w_calculate_hooks */
969         }
970
971         if (next_hop) uac_r->dialog->dst_uri = *next_hop;
972         w_calculate_hooks(uac_r->dialog);
973
974         if(uac_r->ssock!=NULL && uac_r->ssock->len>0
975                         && uac_r->dialog->send_sock==NULL) {
976                 /* set local send socket */
977                 uac_r->dialog->send_sock = lookup_local_socket(uac_r->ssock);
978         }
979
980         return t_uac(uac_r);
981
982  err:
983         /* callback parameter must be freed outside of tm module
984         if (cbp) shm_free(cbp); */
985         return -1;
986 }
987
988
989 /*
990  * Send a transactional request, no dialogs involved
991  * WARNING: writes uac_r->dialog
992  */
993 int request(uac_req_t *uac_r, str* ruri, str* to, str* from, str *next_hop)
994 {
995         str callid, fromtag;
996         dlg_t* dialog;
997         int res;
998
999         if (check_params(uac_r, to, from) < 0) goto err;
1000
1001         if (uac_r->callid == NULL || uac_r->callid->len <= 0)
1002             generate_callid(&callid);
1003         else
1004             callid = *uac_r->callid;
1005         generate_fromtag(&fromtag, &callid);
1006
1007         if (new_dlg_uac(&callid, &fromtag, DEFAULT_CSEQ, from, to, &dialog) < 0) {
1008                 LM_ERR("Error while creating temporary dialog\n");
1009                 goto err;
1010         }
1011
1012         if (ruri) {
1013                 dialog->rem_target.s = ruri->s;
1014                 dialog->rem_target.len = ruri->len;
1015                 /* hooks will be set from w_calculate_hooks */
1016         }
1017
1018         if (next_hop) dialog->dst_uri = *next_hop;
1019         w_calculate_hooks(dialog);
1020
1021         /* WARNING:
1022          * to be clean it should be called
1023          *   set_dlg_target(dialog, ruri, next_hop);
1024          * which sets both uris if given [but it duplicates them in shm!]
1025          *
1026          * but in this case the _ruri parameter in set_dlg_target
1027          * must be optional (it is needed now) and following hacks
1028          *   dialog->rem_target.s = 0;
1029          *   dialog->dst_uri.s = 0;
1030          * before freeing dialog here must be removed
1031          */
1032         uac_r->dialog = dialog;
1033
1034         if(uac_r->ssock!=NULL && uac_r->ssock->len>0
1035                         && uac_r->dialog->send_sock==NULL) {
1036                 /* set local send socket */
1037                 uac_r->dialog->send_sock = lookup_local_socket(uac_r->ssock);
1038         }
1039
1040         res = t_uac(uac_r);
1041         dialog->rem_target.s = 0;
1042         dialog->dst_uri.s = 0;
1043         free_dlg(dialog);
1044         uac_r->dialog = 0;
1045         return res;
1046
1047  err:
1048         /* callback parameter must be freed outside of tm module
1049         if (cp) shm_free(cp); */
1050         return -1;
1051 }