parser changed to make body to point to body (w/o LWS), have a len
[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-27 fifo:t_uac_dlg completed (jiri)
48  * 2003-01-23 t_uac_dlg now uses get_out_socket (jiri)
49  */
50
51
52 #include "defs.h"
53
54
55 #include <stdlib.h>
56 #include <sys/types.h>
57 #include <unistd.h>
58 #include <stdio.h>
59 #include <errno.h>
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 #include <fcntl.h>
63 #include <signal.h>
64 #include <limits.h>
65 #include <string.h>
66 #include "../../parser/parse_from.h"
67 #include "../../parser/msg_parser.h"
68 #include "../../dprint.h"
69 #include "../../ut.h"
70 #include "../../hash_func.h"
71 #include "../../md5utils.h"
72 #include "../../mem/mem.h"
73 #include "../../fifo_server.h"
74 #include "../../error.h"
75 #include "../../pt.h"
76 #include "../../crc.h"
77 #include "t_funcs.h"
78 #include "config.h"
79 #include "sip_msg.h"
80 #include "ut.h"
81 #include "t_msgbuilder.h"
82 #include "uac.h"
83
84 /* header fields which are explicitely processed and are not copied
85  * from FIFO line-by-line
86  */
87 #define skip_hf(_hf) (((_hf)->type==HDR_FROM) || ((_hf)->type==HDR_TO) \
88         || ((_hf)->type==HDR_CALLID) || ((_hf)->type==HDR_CSEQ))
89
90 /* Call-ID has the following form: <callid_nr>-<pid>@<ip>
91  * callid_nr is initialized as a random number and continually
92  * increases; -<pid>@<ip> is kept in callid_suffix
93  */
94
95 #define CALLID_SUFFIX_LEN (1 /* - */ + 5 /* pid */ \
96         + 42 /* embedded v4inv6 address can be looong '128.' */ \
97         + 2 /* parenthessis [] */ + 1 /* ZT 0 */ \
98         + 16 /* one never knows ;-) */ )
99 #define CALLID_NR_LEN 20
100
101 /* the character which separates random from constant part */
102 #define CID_SEP '-'
103
104 /* length of FROM tags */
105 #define FROM_TAG_LEN (MD5_LEN +1 /* - */ + CRC16_LEN)
106
107 struct str_list {
108         str s;
109         struct str_list *next;
110 };
111
112 static unsigned long callid_nr;
113 static char *callid_suffix;
114 static int callid_suffix_len;
115 static int rand_len;    /* number of chars to display max rand */
116 static char callid[CALLID_NR_LEN+CALLID_SUFFIX_LEN];
117
118 #ifndef DEPRECATE_OLD_STUFF
119 char *uac_from="\"UAC Account\" <sip:uac@dev.null:9>";
120 str uac_from_str;
121 #endif
122
123 static char from_tag[ FROM_TAG_LEN+1 ];
124
125
126
127 int uac_init() {
128
129         int i; 
130         unsigned long uli;
131         int rand_len_bits;
132         int rand_cnt; /* number of rands() to be long enough */
133         int rand_bits; /* length of rands() in bits */
134         str src[3];
135
136         if (RAND_MAX<TABLE_ENTRIES) {
137                 LOG(L_WARN, "Warning: uac does not spread "
138                         "accross the whole hash table\n");
139         }
140
141         /* calculate the initial call-id */
142
143         /* how many bits and chars do we need to display the 
144          * whole ULONG number */
145         for (rand_len_bits=0,uli=ULONG_MAX;uli;
146                         uli>>=1, rand_len_bits++ );
147         rand_len=rand_len_bits/4;
148         if (rand_len>CALLID_NR_LEN) {
149                 LOG(L_ERR, "ERROR: Too small callid buffer\n");
150                 return -1;
151         }
152
153         /* how long are the rand()s ? */
154         for (rand_bits=0,i=RAND_MAX;i;i>>=1,rand_bits++);
155         /* how many rands() fit in the ULONG ? */
156         rand_cnt=rand_len_bits / rand_bits;
157
158         /* now fill in the callid with as many random
159          * numbers as you can + 1 */
160         callid_nr=rand(); /* this is the + 1 */
161         while(rand_cnt) {
162                 rand_cnt--;
163                 callid_nr<<=rand_bits;
164                 callid_nr|=rand();
165         }
166         callid_suffix=callid+rand_len;
167         DBG("CALLID initialization: %lx (len=%d)\n", 
168                         callid_nr, rand_len );
169         DBG("CALLID0=%0*lx\n", rand_len, callid_nr );
170
171
172         /* calculate the initial From tag */
173
174         src[0].s="Long live SER server";
175         src[0].len=strlen(src[0].s);
176         src[1].s=sock_info[bind_idx].address_str.s;
177         src[1].len=strlen(src[1].s);
178         src[2].s=sock_info[bind_idx].port_no_str.s;
179         src[2].len=strlen(src[2].s);
180
181         MDStringArray( from_tag, src, 3 );
182         from_tag[MD5_LEN]=CID_SEP;
183
184 #ifndef DEPRECATE_OLD_STUFF
185         uac_from_str.s = uac_from;
186         uac_from_str.len = strlen(uac_from);
187 #endif
188
189         return 1;
190 }
191
192
193 int uac_child_init( int rank ) 
194 {
195         callid_suffix_len=snprintf(callid_suffix,CALLID_SUFFIX_LEN,
196                         "%c%d@%.*s", CID_SEP, my_pid(), 
197                         sock_info[bind_idx].address_str.len,
198                         sock_info[bind_idx].address_str.s );
199         if (callid_suffix_len==-1 || callid_suffix_len>=CALLID_SUFFIX_LEN) {
200                 LOG(L_ERR, "ERROR: uac_child_init: buffer too small\n");
201                 return -1;
202         }
203         DBG("DEBUG: callid_suffix: %s\n", callid_suffix );
204         return 1;
205 }
206
207 #ifndef DEPRECATE_OLD_STUFF
208 int t_uac( str *msg_type, str *dst, 
209         str *headers, str *body, str *from, 
210         transaction_cb completion_cb, void *cbp, 
211         dlg_t dlg)
212 {
213
214         int r;
215         struct cell *new_cell;
216         struct proxy_l *proxy;
217         int branch;
218         int ret;
219         unsigned int req_len;
220         char *buf;
221         union sockaddr_union to;
222         struct socket_info* send_sock;
223         struct retr_buf *request;
224         str dummy_from;
225         str callid_s;
226         str fromtag;
227
228         /* make -Wall shut up */
229         ret=0;
230
231         proxy=uri2proxy( dst );
232         if (proxy==0) {
233                 ser_error=ret=E_BAD_ADDRESS;
234                 LOG(L_ERR, "ERROR: t_uac: can't create a dst proxy\n");
235                 goto done;
236         }
237         branch=0;
238         /* might go away -- we ignore it in send_pr_buffer anyway */
239         /* T->uac[branch].request.to_len=sizeof(union sockaddr_union); */
240         hostent2su(&to, &proxy->host, proxy->addr_idx, 
241                 (proxy->port)?htons(proxy->port):htons(SIP_PORT));
242         /* send_sock=get_send_socket( &to, PROTO_UDP ); */
243         send_sock=get_out_socket( &to, PROTO_UDP );
244         if (send_sock==0) {
245                 LOG(L_ERR, "ERROR: t_uac: no corresponding listening socket "
246                         "for af %d\n", to.s.sa_family );
247                 ret=E_NO_SOCKET;
248                 goto error00;
249         }
250
251         /* update callid */
252         /* generate_callid(); */
253         callid_nr++;
254         r=snprintf(callid, rand_len+1, "%0*lx", rand_len, callid_nr );
255         if (r==-1 || r>=rand_len+1) {
256                 LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
257                 goto error00;
258         }
259         /* fix the ZT 0 */
260         callid[rand_len]=CID_SEP;
261         callid_s.s=callid;
262         callid_s.len=rand_len+callid_suffix_len;
263         DBG("DEBUG: sufix_len = %d\n",callid_suffix_len);
264         DBG("DEBUG: NEW CALLID:%.*s[%d]:\n", callid_s.len, callid_s.s 
265                 , callid_s.len);
266         new_cell = build_cell( NULL ) ; 
267         if (!new_cell) {
268                 ret=E_OUT_OF_MEM;
269                 LOG(L_ERR, "ERROR: t_uac: short of cell shmem\n");
270                 goto error00;
271         }
272         new_cell->completion_cb=completion_cb;
273         new_cell->cbp=cbp;
274         /* cbp is installed -- tell error handling bellow not to free it */
275         cbp=0;
276         new_cell->is_invite=msg_type->len==INVITE_LEN 
277                 && memcmp(msg_type->s, INVITE, INVITE_LEN)==0;
278         new_cell->local=1;
279         new_cell->kr=REQ_FWDED;
280
281
282         request=&new_cell->uac[branch].request;
283         request->to=to;
284         request->send_sock=send_sock;
285
286         /* need to put in table to calculate label which is needed for printing */
287         LOCK_HASH(new_cell->hash_index);
288         insert_into_hash_table_unsafe(  new_cell );
289         UNLOCK_HASH(new_cell->hash_index);
290
291         if (from) dummy_from=*from; else { dummy_from.s=0; dummy_from.len=0; }
292         /* calculate from tag from callid */
293         crcitt_string_array(&from_tag[MD5_LEN+1], &callid_s, 1 );
294         fromtag.s=from_tag; fromtag.len=FROM_TAG_LEN;
295         buf=build_uac_request(  *msg_type, *dst, 
296                         dummy_from, fromtag,
297                         DEFAULT_CSEQ, callid_s, 
298                         *headers, *body, branch,
299                         new_cell, /* t carries hash_index, label, md5,
300                                 uac[].send_sock and other pieces of
301                                 information needed to print a message*/
302                 &req_len );
303         if (!buf) {
304                 ret=E_OUT_OF_MEM;
305                 LOG(L_ERR, "ERROR: t_uac: short of req shmem\n");
306                 goto error01;
307         }      
308         new_cell->method.s=buf;new_cell->method.len=msg_type->len;
309
310
311         request->buffer = buf;
312         request->buffer_len = req_len;
313         new_cell->nr_of_outgoings++;
314
315
316         proxy->tx++;
317         proxy->tx_bytes+=req_len;
318
319         if (SEND_BUFFER( request)==-1) {
320                 LOG(L_ERR, "ERROR: t_uac: UAC sending to %.*s failed\n",
321                         dst->len, dst->s );
322                 proxy->errors++;
323                 proxy->ok=0;
324         }
325         start_retr( request );
326
327         /* success */
328         return 1;
329
330 error01:
331         LOCK_HASH(new_cell->hash_index);
332         remove_from_hash_table_unsafe( new_cell );
333         UNLOCK_HASH(new_cell->hash_index);
334         free_cell(new_cell);
335 error00:
336         free_proxy( proxy );
337         free( proxy );
338 done: 
339         /* if we did not install cbp, release it now */
340         if (cbp) shm_free(cbp);
341         return ser_error=ret;
342 }
343 #endif
344
345 static struct socket_info *uri2sock( str *uri, union sockaddr_union *to_su )
346 {
347         struct proxy_l *proxy;
348         struct socket_info* send_sock;
349
350         proxy = uri2proxy(uri);
351         if (proxy == 0) {
352                 ser_error = E_BAD_ADDRESS;
353                 LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
354                 return 0;
355         }
356
357         hostent2su(to_su, &proxy->host, proxy->addr_idx, 
358                         (proxy->port) ? htons(proxy->port) : htons(SIP_PORT));
359         send_sock=get_out_socket(to_su, PROTO_UDP);
360         if (send_sock == 0) {
361                 LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
362                                                 to_su->s.sa_family );
363                 ser_error = E_NO_SOCKET;
364         }
365
366
367         free_proxy(proxy);
368         free(proxy);
369         return send_sock;
370 }
371         
372
373
374 /*
375  * Send a request within a dialog
376  * 
377  * Some parameters are required, some are optional (i.e., ephemeral,
378  * default or empty values are created if 0 is passed as parameter). The
379  * optional parameters are typically used to set some header fields
380  * to dialog-related values (as opposed to having them set to
381  * ephemeral values).
382  *
383  * Required:
384  * - msg ..   specifies type of message, such as "OPTIONS"
385  * - ruri ..  specifies request URI; 
386  * - from ..  value of From header field (if it already includes from tag, 
387  *            the fromtag parameter MUST point to en empty string; if 
388  *            fromtag is 0, an ephemeral tag is always appended)
389  * - to ...   value of To header field (if it already includes to tag in it,
390  *            or you do not wish to set a to-tag the totag parameter MUST be 0)
391  * 
392  * Optional:
393  * - dst     transport destination (expressed as URI) -- if present,
394  *           request is physically forwarded to address indicated in it,
395  *           overriding the transport address in ruri; useful for use with 
396  *           outbound proxies or loose routers (that is where the first 
397  *           element of route set comes in)
398  * - fromtag from HF tag -- dialog-less applications do not to set it (==0),
399  *           in which case an ephemeral value is created; if fromtag present,
400  *           its appended to the From header field; it may be also present 
401  *           and point to an empty string -- that only makes sense if
402  *           application includes the tag in From and does not care to
403  *           separate the tag from the rest of header field
404  * - totag   To HF tag; if 0, no to-tag is appended (unless it is already
405  *           part of to)
406  * - cid ..  callid; if 0, ephemeral value is created; transactions
407  *           within a dialog need to set this value to dialog's callid
408  * - cseq .. CSeq; if 0, default value (DEFAULT_CSEQ) is used; transactions
409  *           within a dialog need to set this value to current local cseq,
410  *           which grows continously with transactions sent
411  * - headers .. block of header fields that will be included in the
412  *           message. It MAY NOT include header fields already described
413  *           in other parameters (From, to, cid, cseq) or created 
414  *           automatically   (Content_length)   otherwise the parameter
415  *           would appear multiple times. It MUST include all additional
416  *           header fields required for a given SIP message, like Content-Type 
417  *           for any messages including a body or Contact for INVITEs.
418  * - body .. if present, body and Content-Length is appended to the 
419  *           SIP message; Content-Type then needs to be present inside
420  *           'headers' parameter
421  * - cb ..   callback to be called when transaction completes; if none
422  *           present, no callback will be called
423  * - cbp ..  callback parameter -- value passed to callback function
424  *           when called
425  *
426  */
427 int t_uac_dlg(str* msg,                     /* Type of the message - MESSAGE, OPTIONS etc. */
428               str* dst,                     /* Real destination (can be different than R-URI) */
429               str* ruri,                    /* Request-URI */
430               str* to,                      /* To - w/o tag*/
431               str* from,                    /* From - w/o tag*/
432               str* totag,                   /* To tag */
433               str* fromtag,                 /* From tag */
434               int* cseq,                    /* Variable holding CSeq */
435               str* cid,                     /* Call-ID */
436               str* headers,                 /* Optional headers including CRLF */
437               str* body,                    /* Message body */
438               transaction_cb completion_cb, /* Callback parameter */
439               void* cbp                     /* Callback pointer */
440               )
441 {
442
443         int r, branch, ret;
444         unsigned int req_len;
445         char *buf;
446         struct cell *new_cell;
447         struct socket_info* send_sock;
448         struct retr_buf *request;
449         str callid_s, ftag, tmp;
450         union sockaddr_union to_su;
451
452         /* make -Wall shut up */
453         ret=0;
454
455         /* check for invalid parameter */
456         if (!msg || !msg->s
457                                 || !ruri || !ruri->s
458                                 || !from || !from->s
459                                 || !to || !to->s ) {
460                 LOG(L_ERR, "ERROR: t_uac_dlg: invalid parameters\n");
461                 ser_error = ret = E_INVALID_PARAMS;
462                 goto done;
463         }
464
465         send_sock=uri2sock( dst? dst: ruri, &to_su );
466         if (send_sock==0) {
467                 LOG(L_ERR, "ERROR: t_uac_dlg: no socket found\n");
468                 goto error00;
469         }
470
471         branch=0;
472              /* No Call-ID given, calculate it */
473         if (cid == 0) {
474                 callid_nr++;
475                 r = snprintf(callid, rand_len + 1, "%0*lx", rand_len, callid_nr);
476                 if (r == -1 || r>=rand_len+1) {
477                         LOG(L_CRIT, "BUG: SORRY, callid calculation failed\n");
478                         goto error00;
479                 }
480
481                      /* fix the ZT 0 */
482                 callid[rand_len] = CID_SEP;
483                 callid_s.s = callid;
484                 callid_s.len = rand_len + callid_suffix_len;
485         }
486
487         new_cell = build_cell(0); 
488         if (!new_cell) {
489                 ret = E_OUT_OF_MEM;
490                 LOG(L_ERR, "ERROR: t_uac: short of cell shmem\n");
491                 goto error00;
492         }
493
494         new_cell->completion_cb = completion_cb;
495         new_cell->cbp = cbp;
496
497         /* cbp is installed -- tell error handling bellow not to free it */
498         cbp = 0;
499
500         new_cell->is_invite = msg->len == INVITE_LEN && memcmp(msg->s, INVITE, INVITE_LEN) == 0;
501         new_cell->local= 1 ;
502         new_cell->kr = REQ_FWDED;
503
504         request = &new_cell->uac[branch].request;
505         request->to = to_su;
506         request->send_sock = send_sock;
507
508         /* need to put in table to calculate label which is needed for printing */
509         LOCK_HASH(new_cell->hash_index);
510         insert_into_hash_table_unsafe(new_cell);
511         UNLOCK_HASH(new_cell->hash_index);
512
513         if (fromtag == 0) {
514                      /* calculate from tag from callid */
515                 crcitt_string_array(&from_tag[MD5_LEN + 1], (cid) ? (cid) : (&callid_s), 1);
516                 ftag.s = from_tag; 
517                 ftag.len = FROM_TAG_LEN;
518         }
519
520         buf = build_uac_request_dlg(msg, 
521                                     ruri,
522                                     to, 
523                                     from,
524                                     totag,
525                                     (fromtag) ? (fromtag) : (&ftag), 
526                                     (cseq) ? (*cseq) : DEFAULT_CSEQ, 
527                                     (cid) ? (cid) : (&callid_s), 
528                                     headers, 
529                                     body, 
530                                     branch,
531                                     new_cell,
532                                     &req_len,
533                                         send_sock);
534         if (!buf) {
535                 ret = E_OUT_OF_MEM;
536                 LOG(L_ERR, "ERROR: t_uac: short of req shmem\n");
537                 goto error01;
538         }
539         new_cell->method.s = buf;
540         new_cell->method.len = msg->len;
541
542         request->buffer = buf;
543         request->buffer_len = req_len;
544         new_cell->nr_of_outgoings++;
545
546 /*
547         proxy->tx++;
548         proxy->tx_bytes += req_len;
549 */
550
551         if (SEND_BUFFER(request) == -1) {
552                 if (dst) {
553                         tmp = *dst;
554                 } else {
555                         tmp = *ruri;
556                 }
557                 LOG(L_ERR, "ERROR: t_uac: UAC sending to \'%.*s\' failed\n", tmp.len, tmp.s);
558 /*
559                 proxy->errors++;
560                 proxy->ok = 0;
561 */
562         }
563         
564         start_retr(request);
565
566         /* success */
567         return 1;
568
569 error01:
570         LOCK_HASH(new_cell->hash_index);
571         remove_from_hash_table_unsafe(new_cell);
572         UNLOCK_HASH(new_cell->hash_index);
573         free_cell(new_cell);
574
575 error00:
576 /*
577         free_proxy(proxy);
578         free(proxy);
579 */
580
581 done: 
582         /* if we did not install cbp, release it now */
583         if (cbp) shm_free(cbp);
584         return ser_error = ret;
585 }
586
587
588 static void fifo_callback( struct cell *t, struct sip_msg *msg,
589         int code, void *param)
590 {
591
592         char *filename;
593         str text;
594
595         DBG("DEBUG: fifo UAC completed with status %d\n", code);
596         if (!t->cbp) {
597                 LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", code);
598                 return;
599         }
600
601         filename=(char *)(t->cbp);
602         get_reply_status(&text,msg,code);
603         if (text.s==0) {
604                 LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
605                 fifo_reply(filename, "500 fifo_callback: get_reply_status failed\n");
606                 return;
607         }
608         fifo_reply(filename, "%.*s", text.len, text.s );
609         pkg_free(text.s);
610         DBG("DEBUG: fifo_callback sucesssfuly completed\n");
611 }       
612
613 #ifndef DEPRECATE_OLD_STUFF
614
615 /* to be obsoleted in favor of fifo_uac_from */
616 int fifo_uac( FILE *stream, char *response_file ) 
617 {
618         str sm, sh, sb, sd; /* method, header, body, dst(outbound) */
619         char method[MAX_METHOD]; /* read buffers for these ... */
620         char header[MAX_HEADER];
621         char body[MAX_BODY];
622         char dst[MAX_DST];
623         char *shmem_file;
624         int fn_len;
625         int ret;
626         int sip_error;
627         char err_buf[MAX_REASON_LEN];
628
629         sm.s=method; sh.s=header; sb.s=body; sd.s=dst;
630         if (!read_line(method, MAX_METHOD, stream,&sm.len)||sm.len==0) {
631                 /* line breaking must have failed -- consume the rest
632                    and proceed to a new request
633                 */
634                 LOG(L_ERR, "ERROR: fifo_uac: method expected\n");
635                 fifo_reply(response_file, 
636                         "400 fifo_uac: method expected");
637                 return 1;
638         }
639         DBG("DEBUG: fifo_uac: method: %.*s\n", sm.len, method );
640         if (!read_line(dst, MAX_DST, stream, &sd.len)||sd.len==0) {
641                 fifo_reply(response_file, 
642                         "400 fifo_uac: destination expected\n");
643                 LOG(L_ERR, "ERROR: fifo_uac: destination expected\n");
644                 return 1;
645         }
646         DBG("DEBUG: fifo_uac:  dst: %.*s\n", sd.len, dst );
647         /* now read header fields line by line */
648         if (!read_line_set(header, MAX_HEADER, stream, &sh.len)) {
649                 fifo_reply(response_file, 
650                         "400 fifo_uac: HFs expected\n");
651                 LOG(L_ERR, "ERROR: fifo_uac: header fields expected\n");
652                 return 1;
653         }
654         DBG("DEBUG: fifo_uac: header: %.*s\n", sh.len, header );
655         /* and eventually body */
656         if (!read_body(body, MAX_BODY, stream, &sb.len)) {
657                 fifo_reply(response_file, 
658                         "400 fifo_uac: body expected\n");
659                 LOG(L_ERR, "ERROR: fifo_uac: body expected\n");
660                 return 1;
661         }
662         DBG("DEBUG: fifo_uac: body: %.*s\n", sb.len, body );
663         DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
664         /* we got it all, initiate transaction now! */
665         if (response_file) {
666                 fn_len=strlen(response_file)+1;
667                 shmem_file=shm_malloc(fn_len);
668                 if (shmem_file==0) {
669                         LOG(L_ERR, "ERROR: fifo_uac: no shmem\n");
670                         fifo_reply(response_file, 
671                                 "500 fifo_uac: no shmem for shmem_file\n");
672                         return 1;
673                 }
674                 memcpy(shmem_file, response_file, fn_len );
675         } else {
676                 shmem_file=0;
677         }
678         ret=t_uac(&sm,&sd,&sh,&sb, 0 /* default from */,
679                 fifo_callback,shmem_file,0 /* no dialog */);
680         if (ret>0) {
681                 if (err2reason_phrase(ret, &sip_error, err_buf,
682                                 sizeof(err_buf), "FIFO/UAC" ) > 0 ) 
683                 {
684                         fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
685                                 ret );
686                 } else {
687                         fifo_reply(response_file, err_buf );
688                 }
689         }
690         return 1;
691 }
692
693
694 /* syntax:
695
696         :t_uac_from:[file] EOL
697         method EOL
698         [from] EOL (if none, server's default from is taken)
699         dst EOL (put in r-uri and To)
700         [CR-LF separated HFs]* EOL
701         EOL
702         [body] EOL
703         EOL
704
705 */
706
707 int fifo_uac_from( FILE *stream, char *response_file ) 
708 {
709         char method[MAX_METHOD];
710         char header[MAX_HEADER];
711         char body[MAX_BODY];
712         char dst[MAX_DST];
713         char from[MAX_FROM];
714         str sm, sh, sb, sd, sf;
715         char *shmem_file;
716         int fn_len;
717         int ret;
718         int sip_error;
719         char err_buf[MAX_REASON_LEN];
720         int err_ret;
721
722         sm.s=method; sh.s=header; sb.s=body; sd.s=dst;sf.s=from;
723
724         if (!read_line(method, MAX_METHOD, stream,&sm.len)||sm.len==0) {
725                 /* line breaking must have failed -- consume the rest
726                    and proceed to a new request
727                 */
728                 LOG(L_ERR, "ERROR: fifo_uac: method expected\n");
729                 fifo_reply(response_file, 
730                         "400 fifo_uac: method expected");
731                 return 1;
732         }
733         DBG("DEBUG: fifo_uac: method: %.*s\n", sm.len, method );
734         if (!read_line(from, MAX_FROM, stream, &sf.len)) {
735                 fifo_reply(response_file, 
736                         "400 fifo_uac: from expected\n");
737                 LOG(L_ERR, "ERROR: fifo_uac: from expected\n");
738                 return 1;
739         }
740         DBG("DEBUG: fifo_uac:  from: %.*s\n", sf.len, from);
741         if (!read_line(dst, MAX_DST, stream, &sd.len)||sd.len==0) {
742                 fifo_reply(response_file, 
743                         "400 fifo_uac: destination expected\n");
744                 LOG(L_ERR, "ERROR: fifo_uac: destination expected\n");
745                 return 1;
746         }
747         DBG("DEBUG: fifo_uac:  dst: %.*s\n", sd.len, dst );
748         /* now read header fields line by line */
749         if (!read_line_set(header, MAX_HEADER, stream, &sh.len)) {
750                 fifo_reply(response_file, 
751                         "400 fifo_uac: HFs expected\n");
752                 LOG(L_ERR, "ERROR: fifo_uac: header fields expected\n");
753                 return 1;
754         }
755         DBG("DEBUG: fifo_uac: header: %.*s\n", sh.len, header );
756         /* and eventually body */
757         if (!read_body(body, MAX_BODY, stream, &sb.len)) {
758                 fifo_reply(response_file, 
759                         "400 fifo_uac: body expected\n");
760                 LOG(L_ERR, "ERROR: fifo_uac: body expected\n");
761                 return 1;
762         }
763         DBG("DEBUG: fifo_uac: body: %.*s\n", sb.len, body );
764         DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
765         /* we got it all, initiate transaction now! */
766         if (response_file) {
767                 fn_len=strlen(response_file)+1;
768                 shmem_file=shm_malloc(fn_len);
769                 if (shmem_file==0) {
770                         LOG(L_ERR, "ERROR: fifo_uac: no shmem\n");
771                         fifo_reply(response_file, 
772                                 "500 fifo_uac: no memory for shmem_file\n");
773                         return 1;
774                 }
775                 memcpy(shmem_file, response_file, fn_len );
776         } else {
777                 shmem_file=0;
778         }
779         /* HACK: there is yet a shortcoming -- if t_uac fails, callback
780            will not be triggered and no feedback will be printed
781            to shmem_file
782         */
783         ret=t_uac(&sm,&sd,&sh,&sb, sf.len==0 ? 0 : &sf /* default from */,
784                 fifo_callback,shmem_file,0 /* no dialog */);
785         if (ret<=0) {
786                 err_ret=err2reason_phrase(ret, &sip_error, err_buf,
787                                 sizeof(err_buf), "FIFO/UAC" ) ;
788                 if (err_ret > 0 )
789                 {
790                         fifo_reply(response_file, "%d %s", sip_error, err_buf );
791                 } else {
792                         fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
793                                 ret );
794                 }
795         }
796         return 1;
797
798 }
799
800 #endif
801
802 static struct str_list *new_str(char *s, int len, struct str_list **last, int *total)
803 {
804         struct str_list *new;
805         new=pkg_malloc(sizeof(struct str_list));
806         if (!new) {
807                 LOG(L_ERR, "ERROR: get_hfblock: not enough mem\n");
808                 return 0;
809         }
810         new->s.s=s;
811         new->s.len=len;
812         new->next=0;
813
814         (*last)->next=new;
815         *last=new;
816         *total+=len;
817
818         return new;
819 }
820
821
822 static char *get_hfblock(str *uri, struct hdr_field *hf, int *l) 
823 {
824         struct str_list sl, *last, *new, *i, *foo;
825         int hf_avail, frag_len, total_len;
826         char *begin, *needle, *dst, *ret, *d;
827         str *sock_name, *portname;
828         union sockaddr_union to_su;
829         struct socket_info* send_sock;
830
831         ret=0; /* pesimist: assume failure */
832         total_len=0;
833         last=&sl;
834         last->next=0;
835         portname=sock_name=0;
836
837         for (; hf; hf=hf->next) {
838                 if (skip_hf(hf)) continue;
839
840                 begin=needle=hf->name.s; 
841                 hf_avail=hf->len;
842
843                 /* substitution loop */
844                 while(hf_avail) {
845                         d=memchr(needle, SUBST_CHAR, hf_avail);
846                         if (!d || d+1>=needle+hf_avail) { /* nothing to substitute */
847                                 new=new_str(begin, hf_avail, &last, &total_len); 
848                                 if (!new) goto error;
849                                 break;
850                         } else {
851                                 frag_len=d-begin;
852                                 d++; /* d not at the second substitution char */
853                                 switch(*d) {
854                                         case SUBST_CHAR:        /* double SUBST_CHAR: IP */
855                                                 /* string before substitute */
856                                                 new=new_str(begin, frag_len, &last, &total_len); 
857                                                 if (!new) goto error;
858                                                 /* substitute */
859                                                 if (!sock_name) {
860                                                         send_sock=uri2sock( uri, &to_su );
861                                                         if (!send_sock) {
862                                                                 LOG(L_ERR, "ERROR: get_hf_block: send_sock failed\n");
863                                                                 goto error;
864                                                         }
865                                                         sock_name=&send_sock->address_str;
866                                                         portname=&send_sock->port_no_str;
867                                                 }
868                                                 new=new_str(sock_name->s, sock_name->len,
869                                                                 &last, &total_len );
870                                                 if (!new) goto error;
871                                                 new=new_str(portname->s, portname->len,
872                                                                 &last, &total_len );
873                                                 if (!new) goto error;
874                                                 /* keep going ... */
875                                                 begin=needle=d+1;hf_avail-=frag_len+2;
876                                                 continue;
877                                         default:
878                                                 /* no valid substitution char -- keep going */
879                                                 hf_avail-=frag_len+1;
880                                                 needle=d;
881                                 }
882                         } /* possible substitute */
883                 } /* substitution loop */
884                 /* proceed to next header */
885                 /* new=new_str(CRLF, CRLF_LEN, &last, &total_len );
886                 if (!new) goto error; */
887                 DBG("DEBUG: get_hf_block: one more hf processed\n");
888         } /* header loop */
889
890
891         /* construct a single header block now */
892         ret=pkg_malloc(total_len);
893         if (!ret) {
894                 LOG(L_ERR, "ERROR: get_hf_block no pkg mem for hf block\n");
895                 goto error;
896         }
897         i=sl.next;
898         dst=ret;
899         while(i) {
900                 foo=i;
901                 i=i->next;
902                 memcpy(dst, foo->s.s, foo->s.len);
903                 dst+=foo->s.len;
904                 pkg_free(foo);
905         }
906         *l=total_len;
907         return ret;
908
909 error:
910         i=sl.next;
911         while(i) {
912                 foo=i;
913                 i=i->next;
914                 pkg_free(foo);
915         }
916         *l=0;
917         return 0;
918 }
919
920 static void fifo_uac_error(char *reply_fifo, int code, char *msg)
921 {
922         LOG(L_ERR, "ERROR: fifo_uac: %s\n", msg ); 
923         fifo_reply(reply_fifo, "%d fifo_uac: %s", code, msg);
924 }
925
926 /* syntax:
927
928         :t_uac_dlg:[file] EOL
929         method EOL
930         r-uri EOL 
931         dst EOL                                 // ("." if no outbound server used)
932                                                         // must be used with dialogs/lr
933         <EOL separated HFs>+    // From and To must be present at least;
934                                                         // dialog-apps must include tag in From
935                                                         // (an ephemeral is appended otherwise)
936                                                         // and supply CSeq/CallId
937         .[EOL]
938         [body] 
939         .EOL
940
941
942         there is also the possibility to have server placed its
943     hostname:portnumber in header fields -- just put double
944         exclamation mark in any of the optional header fields
945         (i.e., any but From/To/CallID,CSeq), they will be 
946         substituted hn:pn
947
948 Example:
949
950 sc fifo t_uac_dlg MESSAGE sip:joe@192.168.2.1 \
951         . \ # no outbound proxy
952         'From:sender@iptel.org;tagd=123'  \ # no to-tag -> ephemeral
953         'To:sender@iptel.org' \
954         'Foo: sip:user@!! '  \ # expansion here
955         'CSEQ: 11 MESSAGE   ' \
956         . \ # EoH
957         .       # empty body
958 ---
959 U 192.168.2.16:5060 -> 192.168.2.1:5060
960 MESSAGE sip:joe@192.168.2.1 SIP/2.0..
961 Via: SIP/2.0/UDP 192.168.2.16;branch=z9hG4bK760c.922ea6a1.0..
962 To: sender@iptel.org..
963 From: sender@iptel.org;tagd=123;tag=5405e669bc2980663aed2624dc31396f-fa77..
964 CSeq: 11 MESSAGE..
965 Call-ID: e863bf56-22255@192.168.2.16..
966 Content-Length: 0..
967 User-Agent: Sip EXpress router (0.8.11pre4-tcp1-locking (i386/linux))..
968 Foo: sip:user@192.168.2.16:5060..
969 ..
970
971
972 */
973
974 int fifo_uac_dlg( FILE *stream, char *response_file ) 
975 {
976         char method_buf[MAX_METHOD];
977         char ruri_buf[MAX_URI_SIZE];
978         char outbound_buf[MAX_URI_SIZE];
979         char header_buf[MAX_HEADER]; 
980         char body_buf[MAX_BODY]; 
981         str method, ruri, outbound, header, body;
982         str hfb; /* header field block */
983         struct sip_uri parsed_ruri, parsed_outbound;
984         str dummy_empty;
985         int fromtag;
986         int cseq;
987         struct cseq_body *parsed_cseq;
988         int i;
989         char c;
990         struct to_body *parsed_from;
991
992
993         char *shmem_file;
994         int fn_len;
995         int ret;
996         int sip_error;
997         char err_buf[MAX_REASON_LEN];
998         int err_ret;
999         struct sip_msg faked_msg;
1000
1001
1002         if (!read_line(method_buf, MAX_METHOD, stream,&method.len)
1003                                         ||method.len==0) {
1004                 /* line breaking must have failed -- consume the rest
1005                    and proceed to a new request
1006                 */
1007                 fifo_uac_error(response_file, 400, "method expected");
1008                 return 1;
1009         }
1010         method.s=method_buf;
1011         DBG("DEBUG: fifo_uac: method: %.*s\n", method.len, method.s );
1012
1013         if (!read_line(ruri_buf, MAX_URI_SIZE, stream, &ruri.len)
1014                                         || ruri.len==0) {
1015                 fifo_uac_error(response_file, 400, "ruri expected");
1016                 return 1;
1017         }
1018         if (parse_uri(ruri_buf, ruri.len, &parsed_ruri) < 0 ) {
1019                 fifo_uac_error(response_file, 400, "ruri invalid\n");
1020                 return 1;
1021         }
1022         ruri.s=ruri_buf;
1023         DBG("DEBUG: fifo_uac:  ruri: %.*s\n", ruri.len, ruri.s);
1024
1025         if (!read_line(outbound_buf, MAX_URI_SIZE, stream, &outbound.len)
1026                                         ||outbound.len==0) {
1027                 fifo_uac_error(response_file, 400, "outbound address expected\n");
1028                 return 1;
1029         }
1030         if (outbound.len==1 && outbound_buf[0]=='.' ) {
1031                 DBG("DEBUG: fifo_uac: outbound empty\n");
1032                 outbound.s=0; outbound.len=0;
1033         } else if (parse_uri(outbound_buf, outbound.len, 
1034                                                         &parsed_outbound) < 0 ) {
1035                 fifo_uac_error(response_file, 400, "outbound uri invalid\n");
1036                 return 1;
1037         } else {
1038                 outbound.s=outbound_buf;
1039                 DBG("DEBUG: fifo_uac:  dst: %.*s\n", outbound.len, outbound.s);
1040         }
1041
1042
1043         /* now read and parse header fields */
1044         if (!read_line_set(header_buf, MAX_HEADER, stream, &header.len)
1045                                         || header.len==0 ) {
1046                 fifo_uac_error(response_file, 400, "HFs expected");
1047                 return 1;
1048         }
1049         header.s=header_buf;
1050         DBG("DEBUG: fifo_uac: header: %.*s\n", header.len, header.s );
1051         /* use SIP parser to look at what is in the FIFO request */
1052         memset(&faked_msg, 0, sizeof(struct sip_msg));
1053         faked_msg.len=header.len; 
1054         faked_msg.buf=faked_msg.orig=faked_msg.unparsed=header_buf;
1055         if (parse_headers(&faked_msg, HDR_EOH, 0)==-1 ) {
1056                         DBG("DEBUG: fifo_uac: parse_headers failed\n");
1057                         fifo_uac_error(response_file, 400, "HFs unparseable");
1058                         goto error;
1059         }
1060         DBG("DEBUG: fifo_uac: parse_headers succeeded\n");
1061
1062         /* and eventually body */
1063         if (!read_body(body_buf, MAX_BODY, stream, &body.len)) {
1064                 fifo_uac_error(response_file, 400, "body expected");
1065                 goto error;
1066         }
1067         body.s=body_buf;
1068         DBG("DEBUG: fifo_uac: body: %.*s\n", body.len, body.s );
1069
1070
1071         /* at this moment, we collected all the things we got, let's
1072          * verify user has not forgotten something */
1073         if (body.len && !faked_msg.content_type) {
1074                 fifo_uac_error(response_file, 400, "Content_type missing");
1075                 goto error;
1076         }
1077         if (body.len && faked_msg.content_length) {
1078                 fifo_uac_error(response_file, 400, "Content_length disallowed");
1079                 goto error;
1080         }
1081         if (!faked_msg.to) {
1082                 fifo_uac_error(response_file, 400, "To missing");
1083                 goto error;
1084         }
1085         if (!faked_msg.from) {
1086                 fifo_uac_error(response_file, 400, "From missing");
1087                 goto error;
1088         }
1089         /* we also need to know if there is from-tag and add it otherwise */
1090         if (parse_from_header(&faked_msg)<0) {
1091                 fifo_uac_error(response_file, 400, "Error in From");
1092                 goto error;
1093         }
1094         parsed_from=(struct to_body*)faked_msg.from->parsed;
1095         fromtag=parsed_from->tag_value.s &&
1096                         parsed_from->tag_value.len;
1097         cseq=0;
1098         if (faked_msg.cseq && (parsed_cseq=get_cseq(&faked_msg))) {
1099                 for (i=0; i<parsed_cseq->number.len; i++ ) {
1100                         c=parsed_cseq->number.s[i];
1101                         if (c>='0' && c<'9' ) cseq=cseq*10+c-'0';
1102                         else {
1103                                 fifo_uac_error(response_file, 400, "non-nummerical CSeq");
1104                                 goto error;
1105                         }
1106                 }
1107                 if (parsed_cseq->method.len!=method.len 
1108                                 || memcmp(parsed_cseq->method.s, method.s, method.len)!=0) {
1109                         fifo_uac_error(response_file, 400, "CSeq method mismatch");
1110                         goto error;
1111                 }
1112         }
1113
1114         hfb.s=get_hfblock(outbound.len ? &outbound : &ruri, 
1115                                         faked_msg.headers, &hfb.len);
1116         if (!hfb.s) {
1117                 fifo_uac_error(response_file, 500, "no mem for hf block");
1118                 goto error;
1119         }
1120
1121
1122         DBG("DEBUG: fifo_uac: EoL -- proceeding to transaction creation\n");
1123         /* we got it all, initiate transaction now! */
1124         if (response_file) {
1125                 fn_len=strlen(response_file)+1;
1126                 shmem_file=shm_malloc(fn_len);
1127                 if (shmem_file==0) {
1128                         fifo_uac_error(response_file, 500, "no shmem");
1129                         goto error01;
1130                 }
1131                 memcpy(shmem_file, response_file, fn_len );
1132         } else {
1133                 shmem_file=0;
1134         }
1135         /* HACK: there is yet a shortcoming -- if t_uac fails, callback
1136            will not be triggered and no feedback will be printed
1137            to shmem_file
1138         */
1139         dummy_empty.s=0; dummy_empty.len=0;
1140         ret=t_uac_dlg( &method, 
1141                 outbound.len ? &outbound: 0,
1142                 &ruri, 
1143                 &faked_msg.to->body,    /* possibly w/to-tag in it */
1144                 &faked_msg.from->body,
1145                 &dummy_empty,                   /* if present, to-tag passed in to */
1146                 fromtag ?                               /* if fromtag present, ... */
1147                         &dummy_empty:           /* ... pass it in from ... */
1148                         0,                                      /* use ephemeral otherwise */
1149                 cseq ? &cseq : 0,
1150                 faked_msg.callid ?
1151                         &faked_msg.callid->body:
1152                         0,
1153                 &hfb,                                           /* headers -- TBD */
1154                 &body,
1155                 fifo_callback, shmem_file );
1156
1157
1158         if (ret<=0) {
1159                 err_ret=err2reason_phrase(ret, &sip_error, err_buf,
1160                                 sizeof(err_buf), "FIFO/UAC" ) ;
1161                 if (err_ret > 0 )
1162                 {
1163
1164                         fifo_uac_error(response_file, sip_error, err_buf);
1165                 } else {
1166                         fifo_uac_error(response_file, 500, "FIFO/UAC error" );
1167 #ifdef _OBSO
1168                         fifo_reply(response_file, "500 FIFO/UAC error: %d\n",
1169                                 ret );
1170 #endif
1171                 }
1172         }
1173
1174 error01:
1175         pkg_free(hfb.s);
1176
1177 error:
1178         /* free_sip_msg(&faked_msg); */
1179         if (faked_msg.headers) free_hdr_field_lst(faked_msg.headers);
1180         return 1;
1181 }