totag clarifications
[sip-router] / modules / tm / uac.c
1 /*
2  * $Id$
3  *
4  * simple UAC for things such as SUBSCRIBE or SMS gateway;
5  * no authentication and other UAC features -- just send
6  * a message, retransmit and await a reply; forking is not
7  * supported during client generation, in all other places
8  * it is -- adding it should be simple
9  *
10  * Copyright (C) 2001-2003 Fhg Fokus
11  *
12  * This file is part of ser, a free SIP server.
13  *
14  * ser is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version
18  *
19  * For a license to use the ser software under conditions
20  * other than those described here, or to purchase support for this
21  * software, please contact iptel.org by e-mail at the following addresses:
22  *    info@iptel.org
23  *
24  * ser is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License 
30  * along with this program; if not, write to the Free Software 
31  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
32  *
33  * ***************************************************
34  *             IMPORTANT NOTE
35  *
36  *    All UACs but t_uac_dlg are being deprecated now
37  *    and will be removed from future versions of TM
38  *    module. Eliminate all dependancies on them asap.
39  *    For backwards compatibility (NOT RECOMMENDED)
40  *    turn off DEPRECATE_OLD_STUFF in defs.h. Similarly,
41  *    there is a new FIFO UAC.
42  *
43  * ****************************************************
44  *
45  * History:
46  * --------
47  * 2003-01-23 t_uac_dlg now uses get_out_socket (jiri)
48  */
49
50
51 #include "defs.h"
52
53
54 #include <stdlib.h>
55 #include <sys/types.h>
56 #include <unistd.h>
57 #include <stdio.h>
58 #include <errno.h>
59 #include <sys/types.h>
60 #include <sys/stat.h>
61 #include <fcntl.h>
62 #include <signal.h>
63 #include <limits.h>
64 #include <string.h>
65 #include "../../parser/parse_from.h"
66 #include "../../parser/msg_parser.h"
67 #include "../../dprint.h"
68 #include "../../ut.h"
69 #include "../../hash_func.h"
70 #include "../../md5utils.h"
71 #include "../../mem/mem.h"
72 #include "../../fifo_server.h"
73 #include "../../error.h"
74 #include "../../pt.h"
75 #include "../../crc.h"
76 #include "t_funcs.h"
77 #include "config.h"
78 #include "sip_msg.h"
79 #include "ut.h"
80 #include "t_msgbuilder.h"
81 #include "uac.h"
82
83 /* Call-ID has the following form: <callid_nr>-<pid>@<ip>
84  * callid_nr is initialized as a random number and continually
85  * increases; -<pid>@<ip> is kept in callid_suffix
86  */
87
88 #define CALLID_SUFFIX_LEN (1 /* - */ + 5 /* pid */ \
89         + 42 /* embedded v4inv6 address can be looong '128.' */ \
90         + 2 /* parenthessis [] */ + 1 /* ZT 0 */ \
91         + 16 /* one never knows ;-) */ )
92 #define CALLID_NR_LEN 20
93
94 /* the character which separates random from constant part */
95 #define CID_SEP '-'
96
97 /* length of FROM tags */
98 #define FROM_TAG_LEN (MD5_LEN +1 /* - */ + CRC16_LEN)
99
100 static unsigned long callid_nr;
101 static char *callid_suffix;
102 static int callid_suffix_len;
103 static int rand_len;    /* number of chars to display max rand */
104 static char callid[CALLID_NR_LEN+CALLID_SUFFIX_LEN];
105
106 #ifndef DEPRECATE_OLD_STUFF
107 char *uac_from="\"UAC Account\" <sip:uac@dev.null:9>";
108 str uac_from_str;
109 #endif
110
111 static char from_tag[ FROM_TAG_LEN+1 ];
112
113
114
115 int uac_init() {
116
117         int i; 
118         unsigned long uli;
119         int rand_len_bits;
120         int rand_cnt; /* number of rands() to be long enough */
121         int rand_bits; /* length of rands() in bits */
122         str src[3];
123
124         if (RAND_MAX<TABLE_ENTRIES) {
125                 LOG(L_WARN, "Warning: uac does not spread "
126                         "accross the whole hash table\n");
127         }
128
129         /* calculate the initial call-id */
130
131         /* how many bits and chars do we need to display the 
132          * whole ULONG number */
133         for (rand_len_bits=0,uli=ULONG_MAX;uli;
134                         uli>>=1, rand_len_bits++ );
135         rand_len=rand_len_bits/4;
136         if (rand_len>CALLID_NR_LEN) {
137                 LOG(L_ERR, "ERROR: Too small callid buffer\n");
138                 return -1;
139         }
140
141         /* how long are the rand()s ? */
142         for (rand_bits=0,i=RAND_MAX;i;i>>=1,rand_bits++);
143         /* how many rands() fit in the ULONG ? */
144         rand_cnt=rand_len_bits / rand_bits;
145
146         /* now fill in the callid with as many random
147          * numbers as you can + 1 */
148         callid_nr=rand(); /* this is the + 1 */
149         while(rand_cnt) {
150                 rand_cnt--;
151                 callid_nr<<=rand_bits;
152                 callid_nr|=rand();
153         }
154         callid_suffix=callid+rand_len;
155         DBG("CALLID initialization: %lx (len=%d)\n", 
156                         callid_nr, rand_len );
157         DBG("CALLID0=%0*lx\n", rand_len, callid_nr );
158
159
160         /* calculate the initial From tag */
161
162         src[0].s="Long live SER server";
163         src[0].len=strlen(src[0].s);
164         src[1].s=sock_info[bind_idx].address_str.s;
165         src[1].len=strlen(src[1].s);
166         src[2].s=sock_info[bind_idx].port_no_str.s;
167         src[2].len=strlen(src[2].s);
168
169         MDStringArray( from_tag, src, 3 );
170         from_tag[MD5_LEN]=CID_SEP;
171
172 #ifndef DEPRECATE_OLD_STUFF
173         uac_from_str.s = uac_from;
174         uac_from_str.len = strlen(uac_from);
175 #endif
176
177         return 1;
178 }
179
180
181 int uac_child_init( int rank ) 
182 {
183         callid_suffix_len=snprintf(callid_suffix,CALLID_SUFFIX_LEN,
184                         "%c%d@%.*s", CID_SEP, my_pid(), 
185                         sock_info[bind_idx].address_str.len,
186                         sock_info[bind_idx].address_str.s );
187         if (callid_suffix_len==-1 || callid_suffix_len>=CALLID_SUFFIX_LEN) {
188                 LOG(L_ERR, "ERROR: uac_child_init: buffer too small\n");
189                 return -1;
190         }
191         DBG("DEBUG: callid_suffix: %s\n", callid_suffix );
192         return 1;
193 }
194
195 #ifndef DEPRECATE_OLD_STUFF
196 int t_uac( str *msg_type, str *dst, 
197         str *headers, str *body, str *from, 
198         transaction_cb completion_cb, void *cbp, 
199         dlg_t dlg)
200 {
201
202         int r;
203         struct cell *new_cell;
204         struct proxy_l *proxy;
205         int branch;
206         int ret;
207         unsigned int req_len;
208         char *buf;
209         union sockaddr_union to;
210         struct socket_info* send_sock;
211         struct retr_buf *request;
212         str dummy_from;
213         str callid_s;
214         str fromtag;
215
216         /* make -Wall shut up */
217         ret=0;
218
219         proxy=uri2proxy( dst );
220         if (proxy==0) {
221                 ser_error=ret=E_BAD_ADDRESS;
222                 LOG(L_ERR, "ERROR: t_uac: can't create a dst proxy\n");
223                 goto done;
224         }
225         branch=0;
226         /* might go away -- we ignore it in send_pr_buffer anyway */
227         /* T->uac[branch].request.to_len=sizeof(union sockaddr_union); */
228         hostent2su(&to, &proxy->host, proxy->addr_idx, 
229                 (proxy->port)?htons(proxy->port):htons(SIP_PORT));
230         /* send_sock=get_send_socket( &to, PROTO_UDP ); */
231         send_sock=get_out_socket( &to, PROTO_UDP );
232         if (send_sock==0) {
233                 LOG(L_ERR, "ERROR: t_uac: no corresponding listening socket "
234                         "for af %d\n", to.s.sa_family );
235                 ret=E_NO_SOCKET;
236                 goto error00;
237         }
238
239         /* update callid */
240         /* generate_callid(); */
241         callid_nr++;
242         r=snprintf(callid, rand_len+1, "%0*lx", rand_len, callid_nr );
243         if (r==-1 || r>=rand_len+1) {
244                 LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
245                 goto error00;
246         }
247         /* fix the ZT 0 */
248         callid[rand_len]=CID_SEP;
249         callid_s.s=callid;
250         callid_s.len=rand_len+callid_suffix_len;
251         DBG("DEBUG: sufix_len = %d\n",callid_suffix_len);
252         DBG("DEBUG: NEW CALLID:%.*s[%d]:\n", callid_s.len, callid_s.s 
253                 , callid_s.len);
254         new_cell = build_cell( NULL ) ; 
255         if (!new_cell) {
256                 ret=E_OUT_OF_MEM;
257                 LOG(L_ERR, "ERROR: t_uac: short of cell shmem\n");
258                 goto error00;
259         }
260         new_cell->completion_cb=completion_cb;
261         new_cell->cbp=cbp;
262         /* cbp is installed -- tell error handling bellow not to free it */
263         cbp=0;
264         new_cell->is_invite=msg_type->len==INVITE_LEN 
265                 && memcmp(msg_type->s, INVITE, INVITE_LEN)==0;
266         new_cell->local=1;
267         new_cell->kr=REQ_FWDED;
268
269
270         request=&new_cell->uac[branch].request;
271         request->to=to;
272         request->send_sock=send_sock;
273
274         /* need to put in table to calculate label which is needed for printing */
275         LOCK_HASH(new_cell->hash_index);
276         insert_into_hash_table_unsafe(  new_cell );
277         UNLOCK_HASH(new_cell->hash_index);
278
279         if (from) dummy_from=*from; else { dummy_from.s=0; dummy_from.len=0; }
280         /* calculate from tag from callid */
281         crcitt_string_array(&from_tag[MD5_LEN+1], &callid_s, 1 );
282         fromtag.s=from_tag; fromtag.len=FROM_TAG_LEN;
283         buf=build_uac_request(  *msg_type, *dst, 
284                         dummy_from, fromtag,
285                         DEFAULT_CSEQ, callid_s, 
286                         *headers, *body, branch,
287                         new_cell, /* t carries hash_index, label, md5,
288                                 uac[].send_sock and other pieces of
289                                 information needed to print a message*/
290                 &req_len );
291         if (!buf) {
292                 ret=E_OUT_OF_MEM;
293                 LOG(L_ERR, "ERROR: t_uac: short of req shmem\n");
294                 goto error01;
295         }      
296         new_cell->method.s=buf;new_cell->method.len=msg_type->len;
297
298
299         request->buffer = buf;
300         request->buffer_len = req_len;
301         new_cell->nr_of_outgoings++;
302
303
304         proxy->tx++;
305         proxy->tx_bytes+=req_len;
306
307         if (SEND_BUFFER( request)==-1) {
308                 LOG(L_ERR, "ERROR: t_uac: UAC sending to %.*s failed\n",
309                         dst->len, dst->s );
310                 proxy->errors++;
311                 proxy->ok=0;
312         }
313         start_retr( request );
314
315         /* success */
316         return 1;
317
318 error01:
319         LOCK_HASH(new_cell->hash_index);
320         remove_from_hash_table_unsafe( new_cell );
321         UNLOCK_HASH(new_cell->hash_index);
322         free_cell(new_cell);
323 error00:
324         free_proxy( proxy );
325         free( proxy );
326 done: 
327         /* if we did not install cbp, release it now */
328         if (cbp) shm_free(cbp);
329         return ser_error=ret;
330 }
331 #endif
332
333
334 /*
335  * Send a request within a dialog
336  * 
337  * Some parameters are required, some are optional (i.e., ephemeral,
338  * default or empty values are created if 0 is passed as parameter). The
339  * optional parameters are typically used to set some header fields
340  * to dialog-related values (as opposed to having them set to
341  * ephemeral values).
342  *
343  * Required:
344  * - msg ..   specifies type of message, such as "OPTIONS"
345  * - ruri ..  specifies request URI; 
346  * - from ..  value of From header field (if it already includes from tag, 
347  *            the fromtag parameter MUST point to en empty string; if 
348  *            fromtag is 0, an ephemeral tag is always appended)
349  * - to ...   value of To header field (if it already includes to tag in it,
350  *            or you do not wish to set a to-tag the totag parameter MUST be 0)
351  * 
352  * Optional:
353  * - dst     transport destination (expressed as URI) -- if present,
354  *           request is physically forwarded to address indicated in it,
355  *           overriding the transport address in ruri; useful for use with 
356  *           outbound proxies or loose routers (that is where the first 
357  *           element of route set comes in)
358  * - fromtag from HF tag -- dialog-less applications do not to set it (==0),
359  *           in which case an ephemeral value is created; if fromtag present,
360  *           its appended to the From header field; it may be also present 
361  *           and point to an empty string -- that only makes sense if
362  *           application includes the tag in From and does not care to
363  *           separate the tag from the rest of header field
364  * - totag   To HF tag; if 0, no to-tag is appended (unless it is already
365  *           part of to)
366  * - cid ..  callid; if 0, ephemeral value is created; transactions
367  *           within a dialog need to set this value to dialog's callid
368  * - cseq .. CSeq; if 0, default value (DEFAULT_CSEQ) is used; transactions
369  *           within a dialog need to set this value to current local cseq,
370  *           which grows continously with transactions sent
371  * - headers .. block of header fields that will be included in the
372  *           message. It MAY NOT include header fields already described
373  *           in other parameters (From, to, cid, cseq) or created 
374  *           automatically   (Content_length)   otherwise the parameter
375  *           would appear multiple times. It MUST include all additional
376  *           header fields required for a given SIP message, like Content-Type 
377  *           for any messages including a body or Contact for INVITEs.
378  * - body .. if present, body and Content-Length is appended to the 
379  *           SIP message; Content-Type then needs to be present inside
380  *           'headers' parameter
381  * - cb ..   callback to be called when transaction completes; if none
382  *           present, no callback will be called
383  * - cbp ..  callback parameter -- value passed to callback function
384  *           when called
385  *
386  */
387 int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OPTIONS etc. */
388               str* dst,                     /* Real destination (can be different than R-URI) */
389               str* ruri,                    /* Request-URI */
390               str* to,                      /* To - w/o tag*/
391               str* from,                    /* From - w/o tag*/
392               str* totag,                   /* To tag */
393               str* fromtag,                 /* From tag */
394               int* cseq,                    /* Variable holding CSeq */
395               str* cid,                     /* Call-ID */
396               str* headers,                 /* Optional headers including CRLF */
397               str* body,                    /* Message body */
398               transaction_cb completion_cb, /* Callback parameter */
399               void* cbp                     /* Callback pointer */
400               )
401 {
402
403         int r, branch, ret;
404         unsigned int req_len;
405         char *buf;
406         struct cell *new_cell;
407         struct proxy_l *proxy;
408         union sockaddr_union to_su;
409         struct socket_info* send_sock;
410         struct retr_buf *request;
411         str callid_s, ftag, tmp;
412
413         /* make -Wall shut up */
414         ret=0;
415
416         /* check for invalid parameter */
417         if (!msg || !msg->s
418                                 || !ruri || !ruri->s
419                                 || !from || !from->s
420                                 || !to || !to->s ) {
421                 LOG(L_ERR, "ERROR: t_uac_dlg: invalid parameters\n");
422                 ser_error = ret = E_INVALID_PARAMS;
423                 goto done;
424         }
425
426         proxy = uri2proxy((dst) ? (dst) : ruri);
427         if (proxy == 0) {
428                 ser_error = ret = E_BAD_ADDRESS;
429                 LOG(L_ERR, "ERROR: t_uac_dlg: Can't create a dst proxy\n");
430                 goto done;
431         }
432
433         branch=0;
434         hostent2su(&to_su, &proxy->host, proxy->addr_idx, (proxy->port) ? htons(proxy->port) : htons(SIP_PORT));
435         send_sock=get_out_socket(&to_su, PROTO_UDP);
436         if (send_sock == 0) {
437                 LOG(L_ERR, "ERROR: t_uac_dlg: no corresponding listening socket for af %d\n", to_su.s.sa_family );
438                 ret = E_NO_SOCKET;
439                 goto error00;
440         }
441         
442              /* No Call-ID given, calculate it */
443         if (cid == 0) {
444                 callid_nr++;
445                 r = snprintf(callid, rand_len + 1, "%0*lx", rand_len, callid_nr);
446                 if (r == -1 || r>=rand_len+1) {
447                         LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
448                         goto error00;
449                 }
450
451                      /* fix the ZT 0 */
452                 callid[rand_len] = CID_SEP;
453                 callid_s.s = callid;
454                 callid_s.len = rand_len + callid_suffix_len;
455         }
456
457         new_cell = build_cell(0); 
458         if (!new_cell) {
459                 ret = E_OUT_OF_MEM;
460                 LOG(L_ERR, "ERROR: t_uac: short of cell shmem\n");
461                 goto error00;
462         }
463
464         new_cell->completion_cb = completion_cb;
465         new_cell->cbp = cbp;
466
467         /* cbp is installed -- tell error handling bellow not to free it */
468         cbp = 0;
469
470         new_cell->is_invite = msg->len == INVITE_LEN && memcmp(msg->s, INVITE, INVITE_LEN) == 0;
471         new_cell->local= 1 ;
472         new_cell->kr = REQ_FWDED;
473
474         request = &new_cell->uac[branch].request;
475         request->to = to_su;
476         request->send_sock = send_sock;
477
478         /* need to put in table to calculate label which is needed for printing */
479         LOCK_HASH(new_cell->hash_index);
480         insert_into_hash_table_unsafe(new_cell);
481         UNLOCK_HASH(new_cell->hash_index);
482
483         if (fromtag == 0) {
484                      /* calculate from tag from callid */
485                 crcitt_string_array(&from_tag[MD5_LEN + 1], (cid) ? (cid) : (&callid_s), 1);
486                 ftag.s = from_tag; 
487                 ftag.len = FROM_TAG_LEN;
488         }
489
490         buf = build_uac_request_dlg(msg, 
491                                     ruri,
492                                     to, 
493                                     from,
494                                     totag,
495                                     (fromtag) ? (fromtag) : (&ftag), 
496                                     (cseq) ? (*cseq) : DEFAULT_CSEQ, 
497                                     (cid) ? (cid) : (&callid_s), 
498                                     headers, 
499                                     body, 
500                                     branch,
501                                     new_cell,
502                                     &req_len,
503                                         send_sock);
504         if (!buf) {
505                 ret = E_OUT_OF_MEM;
506                 LOG(L_ERR, "ERROR: t_uac: short of req shmem\n");
507                 goto error01;
508         }
509         new_cell->method.s = buf;
510         new_cell->method.len = msg->len;
511
512         request->buffer = buf;
513         request->buffer_len = req_len;
514         new_cell->nr_of_outgoings++;
515
516         proxy->tx++;
517         proxy->tx_bytes += req_len;
518
519         if (SEND_BUFFER(request) == -1) {
520                 if (dst) {
521                         tmp = *dst;
522                 } else {
523                         tmp = *ruri;
524                 }
525                 LOG(L_ERR, "ERROR: t_uac: UAC sending to \'%.*s\' failed\n", tmp.len, tmp.s);
526                 proxy->errors++;
527                 proxy->ok = 0;
528         }
529         
530         start_retr(request);
531
532         /* success */
533         return 1;
534
535 error01:
536         LOCK_HASH(new_cell->hash_index);
537         remove_from_hash_table_unsafe(new_cell);
538         UNLOCK_HASH(new_cell->hash_index);
539         free_cell(new_cell);
540
541 error00:
542         free_proxy(proxy);
543         free(proxy);
544
545 done: 
546         /* if we did not install cbp, release it now */
547         if (cbp) shm_free(cbp);
548         return ser_error = ret;
549 }
550
551
552 static void fifo_callback( struct cell *t, struct sip_msg *msg,
553         int code, void *param)
554 {
555
556         char *filename;
557         str text;
558
559         DBG("DEBUG: fifo UAC completed with status %d\n", code);
560         if (!t->cbp) {
561                 LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", code);
562                 return;
563         }
564
565         filename=(char *)(t->cbp);
566         get_reply_status(&text,msg,code);
567         if (text.s==0) {
568                 LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
569                 fifo_reply(filename, "500 fifo_callback: get_reply_status failed\n");
570                 return;
571         }
572         fifo_reply(filename, "%.*s", text.len, text.s );
573         pkg_free(text.s);
574         DBG("DEBUG: fifo_callback sucesssfuly completed\n");
575 }       
576
577 /* to be obsoleted in favor of fifo_uac_from */
578 int fifo_uac( FILE *stream, char *response_file ) 
579 {
580         char method[MAX_METHOD];
581         char header[MAX_HEADER];
582         char body[MAX_BODY];
583         char dst[MAX_DST];
584         str sm, sh, sb, sd;
585         char *shmem_file;
586         int fn_len;
587         int ret;
588         int sip_error;
589         char err_buf[MAX_REASON_LEN];
590
591         sm.s=method; sh.s=header; sb.s=body; sd.s=dst;
592         if (!read_line(method, MAX_METHOD, stream,&sm.len)||sm.len==0) {
593                 /* line breaking must have failed -- consume the rest
594                    and proceed to a new request
595                 */
596                 LOG(L_ERR, "ERROR: fifo_uac: method expected\n");
597                 fifo_reply(response_file, 
598                         "400 fifo_uac: method expected");
599                 return 1;
600         }
601         DBG("DEBUG: fifo_uac: method: %.*s\n", sm.len, method );
602         if (!read_line(dst, MAX_DST, stream, &sd.len)||sd.len==0) {
603                 fifo_reply(response_file, 
604                         "400 fifo_uac: destination expected\n");
605                 LOG(L_ERR, "ERROR: fifo_uac: destination expected\n");
606                 return 1;
607         }
608         DBG("DEBUG: fifo_uac:  dst: %.*s\n", sd.len, dst );
609         /* now read header fields line by line */
610         if (!read_line_set(header, MAX_HEADER, stream, &sh.len)) {
611                 fifo_reply(response_file, 
612                         "400 fifo_uac: HFs expected\n");
613                 LOG(L_ERR, "ERROR: fifo_uac: header fields expected\n");
614                 return 1;
615         }
616         DBG("DEBUG: fifo_uac: header: %.*s\n", sh.len, header );
617         /* and eventually body */
618         if (!read_body(body, MAX_BODY, stream, &sb.len)) {
619                 fifo_reply(response_file, 
620                         "400 fifo_uac: body expected\n");
621                 LOG(L_ERR, "ERROR: fifo_uac: body expected\n");
622                 return 1;
623         }
624         DBG("DEBUG: fifo_uac: body: %.*s\n", sb.len, body );
625         DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
626         /* we got it all, initiate transaction now! */
627         if (response_file) {
628                 fn_len=strlen(response_file)+1;
629                 shmem_file=shm_malloc(fn_len);
630                 if (shmem_file==0) {
631                         LOG(L_ERR, "ERROR: fifo_uac: no shmem\n");
632                         fifo_reply(response_file, 
633                                 "500 fifo_uac: no shmem for shmem_file\n");
634                         return 1;
635                 }
636                 memcpy(shmem_file, response_file, fn_len );
637         } else {
638                 shmem_file=0;
639         }
640         ret=t_uac(&sm,&sd,&sh,&sb, 0 /* default from */,
641                 fifo_callback,shmem_file,0 /* no dialog */);
642         if (ret>0) {
643                 if (err2reason_phrase(ret, &sip_error, err_buf,
644                                 sizeof(err_buf), "FIFO/UAC" ) > 0 ) 
645                 {
646                         fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
647                                 ret );
648                 } else {
649                         fifo_reply(response_file, err_buf );
650                 }
651         }
652         return 1;
653 }
654
655 #ifndef DEPRECATE_OLD_STUFF
656
657 /* syntax:
658
659         :t_uac_from:[file] EOL
660         method EOL
661         [from] EOL (if none, server's default from is taken)
662         dst EOL (put in r-uri and To)
663         [CR-LF separated HFs]* EOL
664         EOL
665         [body] EOL
666         EOL
667
668 */
669
670 int fifo_uac_from( FILE *stream, char *response_file ) 
671 {
672         char method[MAX_METHOD];
673         char header[MAX_HEADER];
674         char body[MAX_BODY];
675         char dst[MAX_DST];
676         char from[MAX_FROM];
677         str sm, sh, sb, sd, sf;
678         char *shmem_file;
679         int fn_len;
680         int ret;
681         int sip_error;
682         char err_buf[MAX_REASON_LEN];
683         int err_ret;
684
685         sm.s=method; sh.s=header; sb.s=body; sd.s=dst;sf.s=from;
686
687         if (!read_line(method, MAX_METHOD, stream,&sm.len)||sm.len==0) {
688                 /* line breaking must have failed -- consume the rest
689                    and proceed to a new request
690                 */
691                 LOG(L_ERR, "ERROR: fifo_uac: method expected\n");
692                 fifo_reply(response_file, 
693                         "400 fifo_uac: method expected");
694                 return 1;
695         }
696         DBG("DEBUG: fifo_uac: method: %.*s\n", sm.len, method );
697         if (!read_line(from, MAX_FROM, stream, &sf.len)) {
698                 fifo_reply(response_file, 
699                         "400 fifo_uac: from expected\n");
700                 LOG(L_ERR, "ERROR: fifo_uac: from expected\n");
701                 return 1;
702         }
703         DBG("DEBUG: fifo_uac:  from: %.*s\n", sf.len, from);
704         if (!read_line(dst, MAX_DST, stream, &sd.len)||sd.len==0) {
705                 fifo_reply(response_file, 
706                         "400 fifo_uac: destination expected\n");
707                 LOG(L_ERR, "ERROR: fifo_uac: destination expected\n");
708                 return 1;
709         }
710         DBG("DEBUG: fifo_uac:  dst: %.*s\n", sd.len, dst );
711         /* now read header fields line by line */
712         if (!read_line_set(header, MAX_HEADER, stream, &sh.len)) {
713                 fifo_reply(response_file, 
714                         "400 fifo_uac: HFs expected\n");
715                 LOG(L_ERR, "ERROR: fifo_uac: header fields expected\n");
716                 return 1;
717         }
718         DBG("DEBUG: fifo_uac: header: %.*s\n", sh.len, header );
719         /* and eventually body */
720         if (!read_body(body, MAX_BODY, stream, &sb.len)) {
721                 fifo_reply(response_file, 
722                         "400 fifo_uac: body expected\n");
723                 LOG(L_ERR, "ERROR: fifo_uac: body expected\n");
724                 return 1;
725         }
726         DBG("DEBUG: fifo_uac: body: %.*s\n", sb.len, body );
727         DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
728         /* we got it all, initiate transaction now! */
729         if (response_file) {
730                 fn_len=strlen(response_file)+1;
731                 shmem_file=shm_malloc(fn_len);
732                 if (shmem_file==0) {
733                         LOG(L_ERR, "ERROR: fifo_uac: no shmem\n");
734                         fifo_reply(response_file, 
735                                 "500 fifo_uac: no memory for shmem_file\n");
736                         return 1;
737                 }
738                 memcpy(shmem_file, response_file, fn_len );
739         } else {
740                 shmem_file=0;
741         }
742         /* HACK: there is yet a shortcoming -- if t_uac fails, callback
743            will not be triggered and no feedback will be printed
744            to shmem_file
745         */
746         ret=t_uac(&sm,&sd,&sh,&sb, sf.len==0 ? 0 : &sf /* default from */,
747                 fifo_callback,shmem_file,0 /* no dialog */);
748         if (ret<=0) {
749                 err_ret=err2reason_phrase(ret, &sip_error, err_buf,
750                                 sizeof(err_buf), "FIFO/UAC" ) ;
751                 if (err_ret > 0 )
752                 {
753                         fifo_reply(response_file, "%d %s", sip_error, err_buf );
754                 } else {
755                         fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
756                                 ret );
757                 }
758         }
759         return 1;
760
761 }
762
763 #endif
764
765
766 static void fifo_uac_error(char *reply_fifo, int code, char *msg)
767 {
768         LOG(L_ERR, "ERROR: fifo_uac: %s\n", msg ); 
769         fifo_reply(reply_fifo, "%d fifo_uac: %s", code, msg);
770 }
771
772 /* syntax:
773
774         :t_uac_dlg:[file] EOL
775         method EOL
776         r-uri EOL 
777         dst EOL                                 // ("." if no outbound server used)
778                                                         // must be used with dialogs/lr
779         <EOL separated HFs>+    // From and To must be present at least;
780                                                         // dialog-apps must include tag in From
781                                                         // (an ephemeral is appended otherwise)
782                                                         // and supply CSeq/CallId
783         .[EOL]
784         [body] 
785         .EOL
786
787 */
788
789 int fifo_uac_dlg( FILE *stream, char *response_file ) 
790 {
791         char method_buf[MAX_METHOD];
792         char ruri_buf[MAX_URI_SIZE];
793         char outbound_buf[MAX_URI_SIZE];
794         char header_buf[MAX_HEADER]; 
795         char body_buf[MAX_BODY]; 
796         str method, ruri, outbound, header, body;
797         struct sip_uri parsed_ruri, parsed_outbound;
798         str dummy_empty;
799         int fromtag;
800         int cseq;
801         struct cseq_body *parsed_cseq;
802         int i;
803         char c;
804         struct to_body *parsed_from;
805
806
807         char *shmem_file;
808         int fn_len;
809         int ret;
810         int sip_error;
811         char err_buf[MAX_REASON_LEN];
812         int err_ret;
813         struct sip_msg faked_msg;
814
815
816         if (!read_line(method_buf, MAX_METHOD, stream,&method.len)
817                                         ||method.len==0) {
818                 /* line breaking must have failed -- consume the rest
819                    and proceed to a new request
820                 */
821                 fifo_uac_error(response_file, 400, "method expected");
822                 return 1;
823         }
824         method.s=method_buf;
825         DBG("DEBUG: fifo_uac: method: %.*s\n", method.len, method.s );
826
827         if (!read_line(ruri_buf, MAX_URI_SIZE, stream, &ruri.len)
828                                         || ruri.len==0) {
829                 fifo_uac_error(response_file, 400, "ruri expected");
830                 return 1;
831         }
832         if (parse_uri(ruri_buf, ruri.len, &parsed_ruri) < 0 ) {
833                 fifo_uac_error(response_file, 400, "ruri invalid\n");
834                 return 1;
835         }
836         ruri.s=ruri_buf;
837         DBG("DEBUG: fifo_uac:  ruri: %.*s\n", ruri.len, ruri.s);
838
839         if (!read_line(outbound_buf, MAX_URI_SIZE, stream, &outbound.len)
840                                         ||outbound.len==0) {
841                 fifo_uac_error(response_file, 400, "outbound address expected\n");
842                 return 1;
843         }
844         if (outbound.len==1 && outbound_buf[0]=='.' ) {
845                 DBG("DEBUG: fifo_uac: outbound empty\n");
846                 outbound.s=0; outbound.len=0;
847         } else if (parse_uri(outbound_buf, outbound.len, 
848                                                         &parsed_outbound) < 0 ) {
849                 fifo_uac_error(response_file, 400, "outbound uri invalid\n");
850                 return 1;
851         } else {
852                 outbound.s=outbound_buf;
853                 DBG("DEBUG: fifo_uac:  dst: %.*s\n", outbound.len, outbound.s);
854         }
855
856
857         /* now read and parse header fields */
858         if (!read_line_set(header_buf, MAX_HEADER, stream, &header.len)
859                                         || header.len==0 ) {
860                 fifo_uac_error(response_file, 400, "HFs expected");
861                 return 1;
862         }
863         header.s=header_buf;
864         DBG("DEBUG: fifo_uac: header: %.*s\n", header.len, header.s );
865         /* use SIP parser to look at what is in the FIFO request */
866         memset(&faked_msg, 0, sizeof(struct sip_msg));
867         faked_msg.len=header.len; 
868         faked_msg.buf=faked_msg.orig=faked_msg.unparsed=header_buf;
869         if (parse_headers(&faked_msg, HDR_EOH, 0)==-1 ) {
870                         DBG("DEBUG: fifo_uac: parse_headers failed\n");
871                         fifo_uac_error(response_file, 400, "HFs unparseable");
872                         goto error;
873         }
874         DBG("DEBUG: fifo_uac: parse_headers succeeded\n");
875
876         /* and eventually body */
877         if (!read_body(body_buf, MAX_BODY, stream, &body.len)) {
878                 fifo_uac_error(response_file, 400, "body expected");
879                 goto error;
880         }
881         body.s=body_buf;
882         DBG("DEBUG: fifo_uac: body: %.*s\n", body.len, body.s );
883
884
885         /* at this moment, we collected all the things we got, let's
886          * verify user has not forgotten something */
887         if (body.len && !faked_msg.content_type) {
888                 fifo_uac_error(response_file, 400, "Content_type missing");
889                 goto error;
890         }
891         if (body.len && faked_msg.content_length) {
892                 fifo_uac_error(response_file, 400, "Content_length disallowed");
893                 goto error;
894         }
895         if (!faked_msg.to) {
896                 fifo_uac_error(response_file, 400, "To missing");
897                 goto error;
898         }
899         if (!faked_msg.from) {
900                 fifo_uac_error(response_file, 400, "From missing");
901                 goto error;
902         }
903         /* we also need to know if there is from-tag and add it otherwise */
904         if (parse_from_header(&faked_msg)<0) {
905                 fifo_uac_error(response_file, 400, "Error in From");
906                 goto error;
907         }
908         parsed_from=(struct to_body*)faked_msg.from->parsed;
909         fromtag=parsed_from->tag_value.s &&
910                         parsed_from->tag_value.len;
911         cseq=0;
912         if (faked_msg.cseq && (parsed_cseq=get_cseq(&faked_msg))) {
913                 for (i=0; i<parsed_cseq->number.len; i++ ) {
914                         c=parsed_cseq->number.s[i];
915                         if (c>='0' && c<'9' ) cseq=cseq*10+c-'0';
916                         else {
917                                 fifo_uac_error(response_file, 400, "non-nummerical CSeq");
918                                 goto error;
919                         }
920                 }
921                 if (parsed_cseq->method.len!=method.len 
922                                 || memcmp(parsed_cseq->method.s, method.s, method.len)!=0) {
923                         fifo_uac_error(response_file, 400, "CSeq method mismatch");
924                         goto error;
925                 }
926         }
927
928
929
930
931         DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
932         /* we got it all, initiate transaction now! */
933         if (response_file) {
934                 fn_len=strlen(response_file)+1;
935                 shmem_file=shm_malloc(fn_len);
936                 if (shmem_file==0) {
937                         fifo_uac_error(response_file, 500, "no shmem");
938                         goto error;
939                 }
940                 memcpy(shmem_file, response_file, fn_len );
941         } else {
942                 shmem_file=0;
943         }
944         /* HACK: there is yet a shortcoming -- if t_uac fails, callback
945            will not be triggered and no feedback will be printed
946            to shmem_file
947         */
948         dummy_empty.s=0; dummy_empty.len=0;
949         ret=t_uac_dlg( &method, 
950                 outbound.len ? &outbound: 0,
951                 &ruri, 
952                 &faked_msg.to->body,    /* possibly w/to-tag in it */
953                 &faked_msg.from->body,
954                 &dummy_empty,                   /* if present, to-tag passed in to */
955                 fromtag ?                               /* if fromtag present, ... */
956                         &dummy_empty:           /* ... pass it in from ... */
957                         0,                                      /* use ephemeral otherwise */
958                 cseq ? &cseq : 0,
959                 faked_msg.callid ?
960                         &faked_msg.callid->body:
961                         0,
962                 0,                                              /* headers -- TBD */
963                 &body,
964                 fifo_callback, shmem_file );
965
966
967         if (ret<=0) {
968                 err_ret=err2reason_phrase(ret, &sip_error, err_buf,
969                                 sizeof(err_buf), "FIFO/UAC" ) ;
970                 if (err_ret > 0 )
971                 {
972
973                         fifo_uac_error(response_file, sip_error, err_buf);
974                 } else {
975                         fifo_uac_error(response_file, 500, "FIFO/UAC error" );
976 #ifdef _OBSO
977                         fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
978                                 ret );
979 #endif
980                 }
981         }
982
983 error:
984         /* free_sip_msg(&faked_msg); */
985         if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers);
986         return 1;
987 }