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