1 /*
2  * Copyright (C) 2006-2007 VozTelecom Sistemas S.L
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21 
22 #include <unistd.h>
23 #include <string.h>
24 #include <arpa/inet.h>
25 #include <sys/types.h>
26 #include <signal.h>
27 #include <poll.h>
28 #include <assert.h>/*assert*/
29 
30 #include "../../core/mem/mem.h"
31 #include "../../core/dprint.h"
32 #include "../../core/str.h"
33 #include "../../core/pt.h"/*process_count*/
34 #include "../../core/ip_addr.h"
35 #include "../../core/tags.h"
36 #include "../../core/error.h"
37 #include "../../core/ut.h"
38 #include "../../core/parser/hf.h"
39 #include "../../core/parser/parse_fline.h"
40 #include "../../core/parser/parser_f.h"/*find_not_quoted*/
41 #include "../../core/parser/parse_to.h"
42 #include "../../core/parser/parse_from.h"
43 #include "../../core/parser/parse_cseq.h"
44 #include "../../core/parser/parse_content.h"
45 #include "../../core/parser/parse_rr.h"/*parse_rr*/
46 #include "../../core/parser/parse_via.h"/*parse_via*/
47 #include "../../core/parser/parse_param.h"/*parse_params*/
48 #include "../../core/parser/parse_uri.h" /*parse_uri*/
49 #include "../../core/parser/msg_parser.h"
50 #include "encode_msg.h"
51 #include "../../modules/tm/t_lookup.h"
52 #include "../../modules/tm/h_table.h"
53 #include "../../modules/tm/dlg.h"
54 #include "seas.h"
55 #include "statistics.h"
56 #include "seas_action.h"
57 #include "seas_error.h"
58 #include "ha.h"
59 
60 #define MAX_HEADER 1024
61 
62 #define SPIRAL_HDR "X-WeSIP-SPIRAL: true"
63 #define SPIRAL_HDR_LEN (sizeof(SPIRAL_HDR)-1)
64 
65 #define RECORD_ROUTE "Record-Route: "
66 #define RECORD_ROUTE_LEN (sizeof(RECORD_ROUTE)-1)
67 
68 #define VIA "Via: "
69 #define VIA_LEN (sizeof(VIA)-1)
70 
71 extern char *seas_tag_suffix;
72 extern char seas_tags[];
73 pid_t my_parent;
74 extern int fifo_pid;
75 
76 static inline struct sip_msg *parse_ac_msg(hdr_flags_t flags,char *start,int len);
77 static inline void free_sip_msg_lite(struct sip_msg *my_msg);
78 static inline int calculate_hooks(dlg_t* _d);
79 
80 static inline int process_input(int fd);
81 static inline int process_pings(struct ha *the_table);
82 static inline int ac_jain_pong(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len);
83 int process_pong(struct ha *the_table,unsigned int seqno);
84 int print_local_uri(as_p as,char processor_id,char *where,int len);
85 void uas_e2e_ack_cb(struct cell* t, int type,struct tmcb_params *rcvd_params);
86 
87 
dispatch_actions(void)88 int dispatch_actions(void)
89 {
90    int fd,n,ret,timeout,elapsed_ms;
91    static int ktimeout;
92    struct pollfd fds[1];
93    struct timeval last,now;
94 
95    /* now the process_no is set, I delete the pt (process_table) global var,
96 	* because it confuses LM_*() */
97    pt=0;
98    fd=my_as->u.as.action_fd;
99    fds[0].fd=fd;
100    fds[0].events=POLLIN|POLLHUP;
101    fds[0].revents=0;
102    my_parent=getppid();
103    snprintf(whoami,MAX_WHOAMI_LEN,"[%.*s] Action dispatcher",my_as->name.len,my_as->name.s);
104    if(jain_ping_timeout && servlet_ping_timeout)
105       ktimeout=jain_ping_timeout<servlet_ping_timeout?jain_ping_timeout:servlet_ping_timeout;
106    else if(jain_ping_timeout)
107       ktimeout=jain_ping_timeout;
108    else if(servlet_ping_timeout)
109       ktimeout=servlet_ping_timeout;
110    /*ac_buffer is pkg_malloc because only this process (action dispatcher) will use it*/
111    if((my_as->u.as.ac_buffer.s = pkg_malloc(AS_BUF_SIZE))==0){
112       LM_ERR("no more pkg mem\n");
113       return -1;
114    }
115    my_as->u.as.ac_buffer.len=0;
116    if(use_ha){
117       timeout=ktimeout;
118       while(1){
119 	 gettimeofday(&last,NULL);
120 	 print_pingtable(&my_as->u.as.jain_pings,-1,1);
121 	 if(0>(n=poll(fds,1,timeout))){
122 	    if(errno==EINTR){
123 	       gettimeofday(&last,NULL);
124 	       continue;
125 	    }else if(errno==EBADF){
126 	       LM_ERR("EBADF !!\n");
127 	    }else{
128 	       LM_ERR("on poll\n");
129 	    }
130 	 }else if(n==0){/*timeout*/
131 	    if (0>(ret=process_pings(&my_as->u.as.jain_pings))) {
132 	       return ret;
133 	    }
134 	    timeout=ktimeout;
135 	 }else{ /*events*/
136 	    if (0>(ret=process_input(fd))) {
137 	       return ret;
138 	    }
139 	    gettimeofday(&now,NULL);
140 	    elapsed_ms=((now.tv_sec-last.tv_sec)*1000)+((now.tv_usec-last.tv_usec)/1000);
141 	    if(elapsed_ms<timeout){
142 	       timeout-=elapsed_ms;
143 	    }else{
144 	       if(0>(ret=process_pings(&my_as->u.as.jain_pings))){
145 		  return ret;
146 	       }
147 	       timeout=ktimeout;
148 	    }
149 	 }
150 	 fds[0].events=POLLIN|POLLHUP;
151 	 fds[0].revents=0;
152       }
153    }else{
154       do{
155 	 ret=process_input(fd);
156       }while(ret>=0);
157    }
158 
159    return 0;
160 }
161 
process_input(int fd)162 static inline int process_input(int fd)
163 {
164    int j,k;
165 
166    k=AS_BUF_SIZE-(my_as->u.as.ac_buffer.len);
167 again:
168    if(0>(j=read(fd,my_as->u.as.ac_buffer.s+my_as->u.as.ac_buffer.len,k))){
169       if(errno==EINTR)
170 	 goto again;
171       LM_ERR("reading data for as %.*s (%s)\n",my_as->name.len,my_as->name.s,strerror(errno));
172       return -1;
173    }else if(j==0){
174       pkg_free(my_as->u.as.ac_buffer.s);
175       close(fd);
176       LM_ERR("read 0 bytes from AS:%.*s\n",my_as->name.len,my_as->name.s);
177       /** we return, so we will exit, so our parent (Event Dispatcher) will receive a sigchld and know
178        * it should tear down the corresponding AS
179        * what still is not clear is what will happen to events that were put in the pipe...
180        */
181       return -2;
182    }
183    (my_as->u.as.ac_buffer.len)+=j;
184    LM_DBG("read %d bytes from AS action socket (total = %d)\n",j,my_as->u.as.ac_buffer.len);
185    if(use_stats)
186       receivedplus();
187    if(my_as->u.as.ac_buffer.len>=10){
188       process_action(&my_as->u.as);
189       LM_DBG("(Action dispatched,buffer.len=%d)\n",my_as->u.as.ac_buffer.len);
190    }
191    return 0;
192 }
193 
194 /**
195  * The ha structure (high availability) uses a circular (ring) buffer. A linked
196  * list could be used, but it would involve a lot of shm_malloc/free, and this
197  * would involve a lot of shm-lock_get/release, which would interfere a lot
198  * with all the SER processes. With a this ring buffer, the lock_get/release only
199  * involve the SEAS processes.
200  * This function scans the ping structures in the buffer, computing the elapsed time
201  * from when the ping was sent, so if the ping has timed out, it increases the
202  * timed_out_pings counter. All the timed-out pings are removed from the buffer (the
203  * begin index is incremented). Because the pings are added always at the end
204  * of the buffer, they will always be ordered in increasing time, so when we find one ping
205  * that has not timed out, the following pings will neither be.
206  *
207  */
process_pings(struct ha * the_table)208 static inline int process_pings(struct ha *the_table)
209 {
210    int i,k,elapsed;
211    struct ping *tmp;
212    struct timeval now;
213 
214    tmp=NULL;
215    gettimeofday(&now,NULL);
216    if(the_table->count==0)
217       return 0;
218    lock_get(the_table->mutex);
219    {
220       print_pingtable(the_table,-1,0);
221       for(i=0;i<the_table->count;i++){
222 	 k=(the_table->begin+i)%the_table->size;
223 	 tmp=the_table->pings+k;
224 	 elapsed=(now.tv_sec-tmp->sent.tv_sec)*1000+(now.tv_usec-tmp->sent.tv_usec)/1000;
225 	 if(elapsed>the_table->timeout){
226 	    LM_DBG("ping timed out %d\n",tmp->id);
227 	    the_table->timed_out_pings++;
228 	 }else{
229 	    the_table->begin=k;
230 	    the_table->count-=i;
231 	    break;
232 	 }
233       }
234    }
235    lock_release(the_table->mutex);
236    return 0;
237 }
238 
239 /* Because TransactionModule organizes statistics based on process_no,
240  * and process_no are only assigned to SER processes (not to Action dispatchers like us ;)
241  * we have to simulate we are the FIFO process, so TM thinks that the transactions WE put
242  * are put by the fifo process...
243 static inline void set_process_no()
244 {
245    int pcnt,i;
246 
247    pcnt=process_count();
248    for(i=0;i<pcnt;i++){
249       if(pt[i].pid==fifo_pid){
250 	 process_no=i;
251 	 LM_DBG("Setting fake process_no to %d (fifo pid=%d)\n",i,fifo_pid);
252 	 return;
253       }
254    }
255    for(i=0;i<pcnt;i++){
256       if(!memcmp(pt[i].desc,"unix domain socket server",26)){
257 	 process_no=i;
258 	 LM_DBG("Setting fake process_no to %d\n",i);
259 	 return;
260       }
261    }
262    LM_ERR("unable to fake process_no\n");
263 }
264 */
265 
266 /**Processes the actions received from the socket.
267  * returns
268  * 	-1 on error
269  * 	0 on success
270  */
process_action(as_p the_as)271 int process_action(as_p the_as)
272 {
273    unsigned int ac_len;
274    unsigned char processor_id,type;
275    unsigned int flags;
276 
277    ac_len=(the_as->ac_buffer.s[0]<<24)|(the_as->ac_buffer.s[1]<<16)|(the_as->ac_buffer.s[2]<<8)|((the_as->ac_buffer.s[3])&0xFF);
278    type=the_as->ac_buffer.s[4];
279    processor_id=the_as->ac_buffer.s[5];
280    flags=(the_as->ac_buffer.s[6]<<24)|(the_as->ac_buffer.s[7]<<16)|(the_as->ac_buffer.s[8]<<8)|((the_as->ac_buffer.s[9])&0xFF);
281    /*yeah, it comes in network byte order*/
282    /*if ac_len > BUF_SIZE then a flag should be put on the AS so that the whole length
283     * of the action is skipped, until a mechanism for handling big packets is implemented*/
284    if(use_stats)
285       stats_reply();
286    if(ac_len>AS_BUF_SIZE){
287       LM_WARN("action too big (%d)!!! should be skipped and"
288 			  " an error returned!\n",ac_len);
289       return -1;
290    }
291    while (the_as->ac_buffer.len>=ac_len) {
292       LM_DBG("Processing action %d bytes long\n",ac_len);
293       switch(type){
294 	 case REPLY_PROV:
295 	 case REPLY_FIN:
296 	    LM_DBG("Processing a REPLY action from AS (length=%d): %.*s\n",
297 				ac_len,the_as->name.len,the_as->name.s);
298 	    ac_reply(the_as,processor_id,flags,the_as->ac_buffer.s+10,ac_len-10);
299 	    break;
300 	 case UAC_REQ:
301 	    LM_DBG("Processing an UAC REQUEST action from AS (length=%d): %.*s\n",
302 				ac_len,the_as->name.len,the_as->name.s);
303 	    ac_uac_req(the_as,processor_id,flags,the_as->ac_buffer.s+10,ac_len-10);
304 	    break;
305 	 case AC_CANCEL:
306 	    LM_DBG("Processing a CANCEL REQUEST action from AS (length=%d): %.*s\n",
307 				ac_len,the_as->name.len,the_as->name.s);
308 	    ac_cancel(the_as,processor_id,flags,the_as->ac_buffer.s+10,ac_len-10);
309 	    break;
310 	 case SL_MSG:
311 	    LM_DBG("Processing a STATELESS MESSAGE action from AS (length=%d): %.*s\n",
312 				ac_len,the_as->name.len,the_as->name.s);
313 	    ac_sl_msg(the_as,processor_id,flags,the_as->ac_buffer.s+10,ac_len-10);
314 	    break;
315 	 case JAIN_PONG:
316 	    LM_DBG("Processing a PONG\n");
317 	    ac_jain_pong(the_as,processor_id,flags,the_as->ac_buffer.s+10,ac_len-10);
318 	    break;
319 	 default:
320 	    LM_DBG("Processing a UNKNOWN TYPE action from AS (length=%d): %.*s\n",
321 				ac_len,the_as->name.len,the_as->name.s);
322 	    break;
323       }
324       memmove(the_as->ac_buffer.s,the_as->ac_buffer.s+ac_len,(the_as->ac_buffer.len)-ac_len);
325       (the_as->ac_buffer.len)-=ac_len;
326       if(the_as->ac_buffer.len>10){
327 	 ac_len=(the_as->ac_buffer.s[0]<<24)|(the_as->ac_buffer.s[1]<<16)|(the_as->ac_buffer.s[2]<<8)|((the_as->ac_buffer.s[3])&0xFF);
328          type=the_as->ac_buffer.s[4];
329          processor_id=the_as->ac_buffer.s[5];
330          flags=(the_as->ac_buffer.s[6]<<24)|(the_as->ac_buffer.s[7]<<16)|(the_as->ac_buffer.s[8]<<8)|((the_as->ac_buffer.s[9])&0xFF);
331       }else{
332 	 return 0;
333       }
334    }
335    return 0;
336 }
337 
ac_jain_pong(as_p the_as,unsigned char processor_id,unsigned int flags,char * action,int len)338 static inline int ac_jain_pong(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
339 {
340    unsigned int seqno;
341    int k;
342    k=0;
343    net2hostL(seqno,action,k);
344    process_pong(&the_as->jain_pings,seqno);
345    return 0;
346 }
347 
process_pong(struct ha * the_table,unsigned int seqno)348 int process_pong(struct ha *the_table,unsigned int seqno)
349 {
350    int i,k,elapsed;
351    struct ping *tmp;
352    struct timeval now;
353 
354    gettimeofday(&now,NULL);
355    tmp=NULL;
356    if(the_table->count==0)
357       return 0;
358    lock_get(the_table->mutex);
359    print_pingtable(the_table,-1,0);
360    for(i=0;i<the_table->count;i++){
361       k=(the_table->begin+i)%the_table->size;
362       tmp=the_table->pings+k;
363       if(tmp->id == seqno){
364 	 elapsed=(now.tv_sec-tmp->sent.tv_sec)*1000+(now.tv_usec-tmp->sent.tv_usec)/1000;
365 	 LM_DBG("Ping-Pong delay: %d (timeout was:%d)\n",elapsed,the_table->timeout);
366 	 if(elapsed>the_table->timeout){
367 	    /*if this ping has timed out, all the more-ancient pings will also be
368 	     * timed out*/
369 	    the_table->timed_out_pings+=i;
370 	 }/*anyway, when we find a ping in the table, we remove all the pings that are more
371 	    ancient (if there are any..)*/
372 	 the_table->count-=(i+1);
373 	 the_table->begin=(k+1)%the_table->size;
374 	 break;
375       }
376    }
377    lock_release(the_table->mutex);
378    return 0;
379 }
380 
381 
382 /**
383  * ac_cancel:
384  * @param the_as Application Server structure which sent this action
385  * @param action action payload
386  * @param len the length of the payload
387  *
388  * This function cancels a previously initiated UAC Transaction.
389  * it receives the HashIndex and Label of the cell being cancelled
390  * and invokes t_cancel_uac from the transactionModule API which
391  * cancels the transaction.
392  *
393  * Returns:
394  * */
395 
ac_cancel(as_p the_as,unsigned char processor_id,unsigned int flags,char * action,int len)396 int ac_cancel(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
397 {
398    unsigned int ret,cancelled_hashIdx,cancelled_label,i;
399    struct sip_msg *my_msg;
400    struct as_uac_param *the_param;
401    struct cell* t_invite;
402    int k,retval,uac_id;
403    str headers,body;
404 
405    body.s=headers.s=NULL;
406    my_msg=NULL;
407    the_param=NULL;
408    i=k=0;
409 
410    net2hostL(uac_id,action,k);
411 
412    net2hostL(cancelled_hashIdx,action,k);
413    net2hostL(cancelled_label,action,k);
414 
415    if(!(headers.s=pkg_malloc(MAX_HEADER))){
416       LM_ERR("Out of Memory!!");
417       goto error;
418    }
419    headers.len=0;
420    if(!(my_msg=pkg_malloc(sizeof(struct sip_msg)))){
421       LM_ERR("out of memory!\n");
422       goto error;
423    }
424    memset(my_msg,0,sizeof(struct sip_msg));
425    my_msg->buf=action+k;
426    my_msg->len=len-k;
427    LM_DBG("Action UAC Message: uac_id:%d processor_id=%d, message:[%.*s]\n",
428 		   uac_id,processor_id,len-4,&action[4]);
429    if(parse_msg(action+k,len-k,my_msg)<0){
430       LM_ERR("parsing sip_msg");
431       goto error;
432    }
433    if(my_msg->first_line.type==SIP_REPLY){
434       LM_ERR("trying to create a UAC with a SIP response!!\n");
435       goto error;
436    }
437    if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
438       LM_ERR("parsing headers\n");
439       goto error;
440    }
441    if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) {
442       LM_ERR("Unable to extract allowed headers!!\n");
443       goto error;
444    }
445    if(flags & SPIRAL_FLAG){
446       memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
447       headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
448       /*headers.s[headers.len]=0;
449       fake_uri.s=pkg_malloc(200);
450       fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);
451 
452       if(fake_uri.len<0){
453 	 SLM_ERR("printing local uri\n");
454 	 goto error;
455       }
456       my_dlg->hooks.next_hop=&fake_uri;*/
457    }
458 
459    headers.s[headers.len]=0;
460 
461    /*let's get the body*/
462    i=(unsigned int)get_content_length(my_msg);
463    if(i!=0){
464       if(!(body.s=pkg_malloc(i))){
465 	 LM_ERR("Out of Memory!");
466 	 goto error;
467       }
468       memcpy(body.s,get_body(my_msg),i);
469       body.len=i;
470       LM_DBG("Trying to construct a Sip Request with: body:%d[%s]"
471 			  " headers:%d[%s]\n", body.len,body.s,headers.len,headers.s);
472    }else{
473       body.s=NULL;
474       body.len=0;
475    }
476 
477    if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
478       LM_ERR("no more share memory\n");
479       goto error;
480    }
481 
482 	if(seas_f.tmb.t_lookup_ident(&t_invite,cancelled_hashIdx,cancelled_label)<0){
483 		LM_ERR("failed to t_lookup_ident hash_idx=%d,"
484 			"label=%d\n", cancelled_hashIdx,cancelled_label);
485 		goto error;
486 	}
487 	seas_f.tmb.unref_cell(t_invite);
488 
489    the_param->who=my_as;
490    the_param->uac_id=uac_id;
491    the_param->processor_id=processor_id;
492    the_param->destroy_cb_set=0;
493 
494    /* registers TMCB_RESPONSE_IN|TMCB_LOCAL_COMPLETED tm callbacks */
495    ret=seas_f.tmb.t_cancel_uac(&headers,&body,cancelled_hashIdx,cancelled_label,uac_cb,(void*)the_param);
496    if (ret == 0) {
497       LM_ERR( "t_cancel_uac failed\n");
498       as_action_fail_resp(uac_id,SE_CANCEL,SE_CANCEL_MSG,SE_CANCEL_MSG_LEN);
499       goto error;
500    }else{
501       the_param->label=ret;
502    }
503 
504 	seas_f.tmb.unref_cell(t_invite);
505    retval=0;
506    goto exit;
507 error:
508    retval = -1;
509    if(the_param)
510       shm_free(the_param);
511 exit:
512    if(headers.s)
513       pkg_free(headers.s);
514    if(body.s)
515       pkg_free(body.s);
516    if(my_msg){
517       if(my_msg->headers)
518 	 free_hdr_field_lst(my_msg->headers);
519       pkg_free(my_msg);
520    }
521    return retval;
522 }
523 
recordroute_diff(struct sip_msg * req,struct sip_msg * resp)524 int recordroute_diff(struct sip_msg *req,struct sip_msg *resp)
525 {
526    struct hdr_field *hf;
527    rr_t *rr1;
528    int i,j,k;
529    i=j=k=0;
530    /* count how many record-route bodies come in the response*/
531    /* this does not work, I think because of siblings
532    for(hf=resp->record_route;hf;hf=hf->sibling,j=0){
533    */
534    for(hf=resp->headers;hf;hf=hf->next,j=0){
535       if(hf->type != HDR_RECORDROUTE_T)
536 	 continue;
537       if(!hf->parsed){
538 	 if(0>parse_rr(hf))
539 	    goto error;
540 	 j=1;
541       }
542       for(rr1=hf->parsed;rr1;rr1=rr1->next){
543 	 i++;
544       }
545       if(j){
546 	 free_rr((rr_t**)(void*)&hf->parsed);
547 	 hf->parsed=NULL;
548       }
549    }
550    /*
551    for(hf=req->record_route;hf;hf=hf->sibling,j=0){
552       */
553    for(hf=req->headers;hf;hf=hf->next,j=0){
554       if(hf->type != HDR_RECORDROUTE_T)
555 	 continue;
556       if(!hf->parsed){
557 	 if(0>parse_rr(hf))
558 	    goto error;
559 	 j=1;
560       }
561       for(rr1=hf->parsed;rr1;rr1=rr1->next){
562 	 k++;
563       }
564       if(j){
565 	 free_rr((rr_t**)(void*)&hf->parsed);
566 	 hf->parsed=NULL;
567       }
568    }
569    return i-k;
570 error:
571    return -1;
572 }
573 
via_diff(struct sip_msg * req,struct sip_msg * resp)574 int via_diff(struct sip_msg *req,struct sip_msg *resp)
575 {
576    struct hdr_field *hf;
577    struct via_body *vb;
578    int i,j,k;
579 
580    i=j=k=0;
581    /* count how many via bodies come in the response*/
582    for(hf=resp->h_via1;hf;hf=next_sibling_hdr(hf)){
583       if(!hf->parsed){
584 	 if((vb=pkg_malloc(sizeof(struct via_body)))==0){
585 	    LM_ERR("Out of mem in via_diff!!\n");
586 	    return -1;
587 	 }
588 	 memset(vb,0,sizeof(struct via_body));
589 	 if(parse_via(hf->body.s,hf->body.s+hf->body.len+1,vb)==0){
590 	    LM_ERR("Unable to parse via in via_diff!\n");
591 	    pkg_free(vb);
592 	    return -1;
593 	 }
594 	 hf->parsed=vb;
595 	 j=1;
596       }
597       for(vb=hf->parsed;vb;vb=vb->next){
598 	 i++;
599       }
600       if(j){
601 	 free_via_list((struct via_body*)hf->parsed);
602 	 hf->parsed=NULL;
603 	 j=0;
604       }
605    }
606    j=0;
607    /* count how many via bodies were in the orig. request*/
608    for(hf=req->h_via1;hf;hf=next_sibling_hdr(hf)){
609       if(!hf->parsed){
610 	 if((vb=pkg_malloc(sizeof(struct via_body)))==0){
611 	    goto error;
612 	 }
613 	 memset(vb,0,sizeof(struct via_body));
614 	 if(parse_via(hf->body.s,hf->body.s+hf->body.len+1,vb)==0){
615 	    goto error;
616 	 }
617 	 hf->parsed=vb;
618 	 j=1;
619       }
620       for(vb=hf->parsed;vb;vb=vb->next){
621 	 k++;
622       }
623       if(j){
624 	 free_via_list((struct via_body*)hf->parsed);
625 	 hf->parsed=NULL;
626 	 j=0;
627       }
628    }
629    return i-k;
630 error:
631    return -1;
632 }
633 
param_free(void * param)634 static void param_free(void *param)
635 {
636    shm_free(param);
637 }
638 /**
639  * ac_reply: UAS transaction Reply action. It replies to an incoming request with a response.
640  * @param the_as The App Server that sent this action.
641  * @param action action
642  * @param len length
643  *
644  * function description
645  *
646  * Returns: what
647  */
ac_reply(as_p the_as,unsigned char processor_id,unsigned int flags,char * action,int len)648 int ac_reply(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
649 {
650    unsigned int hash_index,label,contentlength;
651    struct cell *c=NULL;
652    struct sip_msg *my_msg;
653    struct to_body *tb;
654    str new_header,body,totag;
655    char *ttag;
656    int i,k,retval;
657    static char headers[MAX_HEADER];
658    struct as_uac_param *the_param;
659 
660    contentlength=0;
661    ttag=NULL;
662    my_msg=NULL;
663    i=k=0;
664    the_param=NULL;
665 
666    net2hostL(hash_index,action,k);
667    net2hostL(label,action,k);
668 
669    if(seas_f.tmb.t_lookup_ident(&c,hash_index,label)<0){
670       LM_ERR("Failed to t_lookup_ident hash_idx=%d,label=%d\n",hash_index,label);
671       goto error;
672    }
673    if(use_stats)
674       action_stat(c);
675    if(c->uas.status>=200){
676       LM_ERR("ac_reply: trying to reply to a \"%.*s\" transaction"
677 	    "that is already in completed state\n",REQ_LINE(c->uas.request).method.len,REQ_LINE(c->uas.request).method.s);
678       goto error;
679    }
680    if (!(my_msg=parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
681       LM_ERR("Failed to parse_ac_msg hash_idx=%d,label=%d\n",hash_index,label);
682       goto error;
683    }
684    tb=(struct to_body*)my_msg->to->parsed;
685    if(tb->tag_value.s && tb->tag_value.len){
686       totag=tb->tag_value;
687    }else{
688       totag.s=NULL;
689       totag.len=0;
690    }
691    LM_DBG("Using totag=[%.*s]\n",totag.len,totag.s);
692    if(my_msg->content_length)
693       contentlength=(unsigned int)(long)my_msg->content_length->parsed;
694    if(0>(i=recordroute_diff(c->uas.request,my_msg))){/*not likely..*/
695       LM_DBG("Seems that request had more RecordRoutes than response...\n");
696       /* This prevents host->proxy->host from working. TODO review recordroute_diff code.
697       goto error; */
698    }else
699       LM_DBG("Recordroute Diff = %d\n",i);
700 
701    if(0>(i=extract_allowed_headers(my_msg,0,i,HDR_VIA_F|HDR_TO_F|HDR_FROM_F|HDR_CSEQ_F|HDR_CALLID_F|HDR_CONTENTLENGTH_F,headers,MAX_HEADER))){
702       LM_ERR("ac_reply() filtering headers !\n");
703       goto error;
704    }
705    headers[i]=0;
706    new_header.s=headers;
707    new_header.len=i;
708 
709    /* If it is INVITE and response is success (>=200 && <300), we mark it as local so that
710     * SER does NOT retransmit the final response (by default, SER retransmit local UAS final
711     * responses...*/
712    if(is_invite(c) && my_msg->first_line.u.reply.statuscode>=200 && my_msg->first_line.u.reply.statuscode<300){
713       c->flags |= T_IS_LOCAL_FLAG;
714       if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
715          LM_ERR("no more share memory\n");
716          goto error;
717       }
718       the_param->processor_id=processor_id;
719       the_param->who=my_as;
720       the_param->destroy_cb_set=0;
721       if (seas_f.tmb.register_tmcb( 0, c, TMCB_E2EACK_IN,uas_e2e_ack_cb, the_param,&param_free)<=0) {
722          LM_ERR("cannot register additional callbacks\n");
723          goto error;
724       }
725    }
726    /*WARNING casting unsigned int to int*/
727    body.len=contentlength;
728    body.s=get_body(my_msg);
729 
730    LM_DBG("Trying to construct a SipReply with: ReasonPhrase:[%.*s] body:[%.*s] headers:[%.*s] totag:[%.*s]\n",\
731 	 my_msg->first_line.u.reply.reason.len,my_msg->first_line.u.reply.reason.s,\
732 	 body.len,body.s,new_header.len,new_header.s,totag.len,totag.s);
733    /* t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
734    if(seas_f.tmb.t_reply_with_body(c,my_msg->first_line.u.reply.statuscode,&(my_msg->first_line.u.reply.reason),&body,&new_header,&totag)<0){
735       LM_ERR("Failed to t_reply\n");
736       goto error;
737    }
738    retval=0;
739    goto exit;
740 error:
741    retval = -1;
742    if(c)
743       seas_f.tmb.unref_cell(c);
744    if(the_param)
745       shm_free(the_param);
746 exit:
747    if(ttag)
748       pkg_free(ttag);
749    if(my_msg){
750       free_sip_msg_lite(my_msg);
751       pkg_free(my_msg);
752    }
753    return retval;
754 }
755 
parse_ac_msg(hdr_flags_t flags,char * start,int len)756 static inline struct sip_msg *parse_ac_msg(hdr_flags_t flags,char *start,int len)
757 {
758    struct sip_msg *my_msg;
759    my_msg=NULL;
760    if(!(my_msg=pkg_malloc(sizeof(struct sip_msg)))){
761       LM_ERR("ac_reply: out of memory!\n");
762       goto error;
763    }
764    memset(my_msg,0,sizeof(struct sip_msg));
765    my_msg->buf=start;
766    my_msg->len=len;
767    LM_DBG("Action Message:[%.*s]\n",len,start);
768    if(0>parse_msg(start,len,my_msg)){
769       LM_ERR("parse_ac_msg: parsing sip_msg");
770       goto error;
771    }
772    if(0>parse_headers(my_msg,flags,0)){
773       LM_ERR("parse_ac_msg: parsing headers\n");
774       goto error;
775    }
776    return my_msg;
777 error:
778    if(my_msg){
779       free_sip_msg_lite(my_msg);
780       pkg_free(my_msg);
781    }
782    return NULL;
783 }
784 
785 /* Actions are composed as follows:
786  * (the action length and type as always= 5 bytes)
787  *
788  * TODO performance speedup: instead of using
789  * dynamically allocated memory for headers,body,totag,reason and my_msg
790  * use static buffers.
791  *
792  */
ac_sl_msg(as_p the_as,unsigned char processor_id,unsigned int flags,char * action,int len)793 int ac_sl_msg(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
794 {
795    struct sip_msg *my_msg;
796    str *uri;
797    struct proxy_l *proxy;
798    rr_t *my_route;
799    int k,retval;
800    //enum sip_protos proto;
801 
802    my_msg=NULL;
803    k=0;
804 
805    proxy=0;
806 
807    if(!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))){
808       LM_ERR("out of memory!\n");
809       goto error;
810    }
811    if(my_msg->first_line.type == SIP_REQUEST)
812       LM_DBG("forwarding request:\"%.*s\" statelessly \n",my_msg->first_line.u.request.method.len+1+\
813 	    my_msg->first_line.u.request.uri.len,my_msg->first_line.u.request.method.s);
814    else
815       LM_DBG("forwarding reply:\"%.*s\" statelessly \n",my_msg->first_line.u.reply.status.len+1+\
816 	    my_msg->first_line.u.reply.reason.len,my_msg->first_line.u.reply.status.s);
817 
818    if (my_msg->route) {
819       if (parse_rr(my_msg->route) < 0) {
820 	 LM_ERR( "Error while parsing Route body\n");
821 	 goto error;
822       }
823       my_route = (rr_t*)my_msg->route->parsed;
824       uri=&(my_route->nameaddr.uri);
825    }else{
826       uri = GET_RURI(my_msg);
827    }
828    set_force_socket(my_msg, grep_sock_info(&my_msg->via1->host,
829                                             my_msg->via1->port,
830                                             my_msg->via1->proto) );
831    /* or also could be:
832       my_msg->force_send_socket=the_as->binds[processor_id].bind_address;
833       not sure which is better...
834       */
835    /*proxy=uri2proxy(uri,PROTO_NONE);
836    if (proxy==0) {
837       LM_ERR("unable to create proxy from URI \n");
838       goto error;
839    }
840    proto=proxy->proto;
841    */
842    //TODO my_msg->recvd
843    if(0>forward_sl_request(my_msg,uri,PROTO_NONE))
844       goto error;
845    retval=0;
846    goto exit;
847 error:
848    retval = -1;
849 exit:
850    if(proxy){
851       free_proxy(proxy);
852       pkg_free(proxy);
853    }
854    if(my_msg){
855       free_sip_msg_lite(my_msg);
856       pkg_free(my_msg);
857    }
858    return retval;
859 }
860 
free_sip_msg_lite(struct sip_msg * my_msg)861 static inline void free_sip_msg_lite(struct sip_msg *my_msg)
862 {
863    if(my_msg){
864       /**should do the same as in free_sip_msg() but w/o freeing my_msg->buf*/
865       if (my_msg->new_uri.s) { pkg_free(my_msg->new_uri.s); my_msg->new_uri.len=0; }
866       if (my_msg->dst_uri.s) { pkg_free(my_msg->dst_uri.s); my_msg->dst_uri.len=0; }
867       if (my_msg->path_vec.s) { pkg_free(my_msg->path_vec.s);my_msg->path_vec.len=0; }
868       if (my_msg->headers)     free_hdr_field_lst(my_msg->headers);
869       if (my_msg->add_rm)      free_lump_list(my_msg->add_rm);
870       if (my_msg->body_lumps)  free_lump_list(my_msg->body_lumps);
871       /* this is not in lump_struct.h, and anyhow it's not supposed to be any lumps
872        * in our messages... or is it?
873       if (my_msg->reply_lump)   free_reply_lump(my_msg->reply_lump);
874       */
875    }
876 }
877 
forward_sl_request(struct sip_msg * msg,str * uri,int proto)878 int forward_sl_request(struct sip_msg *msg,str *uri,int proto)
879 {
880 	struct dest_info dst;
881 	int ret;
882 
883 	ret = -1;
884 
885 #ifdef USE_DNS_FAILOVER
886         if ((uri2dst(NULL,&dst, msg,  uri, proto)==0) || (dst.send_sock==0))
887 #else
888         if ((uri2dst(&dst, msg,  uri, proto)==0) || (dst.send_sock==0))
889 #endif
890         {
891 		LM_ERR("no socket found\n");
892 		return -1;
893 	}
894 
895         LM_DBG("Sending:\n%.*s.\n", (int)msg->len,msg->buf);
896         if (msg_send(&dst, msg->buf,msg->len)<0){
897            LM_ERR("Error sending message !!\n");
898            return -1;
899         }
900 	return ret;
901 }
902 
903 
904 
905 /*Actions are composed as follows:
906  * (the action length and type as always= 5 bytes)
907  * 4:uac_id
908  *
909  * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp)
910  * TODO performance speedup: instead of using
911  * dynamically allocated memory for headers,body,totag,reason and my_msg
912  * use static buffers.
913  *
914  */
ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char * action,int len)915 int ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
916 {
917    unsigned int cseq;
918    char err_buf[MAX_REASON_LEN];
919    struct sip_msg *my_msg;
920    struct to_body *fb,*tb;
921    struct cseq_body *cseqb;
922    struct as_uac_param *the_param;
923    dlg_t *my_dlg;
924    int k,retval,uac_id,sip_error,ret,err_ret;
925    long clen;
926    str headers,body,fake_uri;
927    uac_req_t uac_r;
928 
929    headers.s=body.s=fake_uri.s=NULL;
930    my_dlg=NULL;
931    my_msg=NULL;
932    the_param=NULL;
933    k=clen=0;
934 
935    net2hostL(uac_id,action,k);
936 
937    if(!(headers.s=pkg_malloc(MAX_HEADER))){
938       LM_ERR("Out of Memory!!");
939       goto error;
940    }
941    headers.len=0;
942    LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id);
943    if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
944       LM_ERR("out of memory!\n");
945       goto error;
946    }
947    if(my_msg->first_line.type==SIP_REPLY){
948       LM_ERR("trying to create a UAC with a SIP response!!\n");
949       goto error;
950    }
951    if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
952       LM_ERR("ERROR:seas:ac_uac_req:parsing headers\n");
953       goto error;
954    }
955    if(parse_from_header(my_msg)<0){
956       LM_ERR("parsing from header ! \n");
957       goto error;
958    }
959    if(check_transaction_quadruple(my_msg)==0){
960       as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0);
961       LM_ERR("Headers missing (to,from,call-id,cseq)?");
962       goto error;
963    }
964    if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) ||
965 	 !(get_from(my_msg)->tag_value.len)){
966       as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0);
967       LM_ERR("From tag missing");
968       goto error;
969    }
970    fb=my_msg->from->parsed;
971    tb=my_msg->to->parsed;
972    cseqb=my_msg->cseq->parsed;
973    if(0!=(str2int(&cseqb->number,&cseq))){
974       LM_DBG("unable to parse CSeq\n");
975       goto error;
976    }
977    if(my_msg->first_line.u.request.method_value != METHOD_ACK &&
978 	 my_msg->first_line.u.request.method_value != METHOD_CANCEL) {
979       /** we trick req_within */
980       cseq--;
981    }
982    if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\
983 	    &(fb->uri),&(tb->uri),&my_dlg) < 0) {
984       as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0);
985       LM_ERR("Error while creating new dialog\n");
986       goto error;
987    }
988    if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) {
989       as_action_fail_resp(uac_id,SE_UAC,
990          "Error adding the display names to the new dialog",0);
991       LM_ERR("failed to add display names to the new dialog\n");
992       goto error;
993    }
994 
995    if(tb->tag_value.s && tb->tag_value.len)
996       shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value);
997    /**Awful hack: to be able to set our own CSeq, from_tag and call-ID we have
998     * to use req_within instead of req_outside (it sets it's own CSeq,Call-ID
999     * and ftag), so we have to simulate that the dialog is already in completed
1000     * state so...
1001     */
1002    server_signature=0;
1003    my_dlg->state = DLG_CONFIRMED;
1004    if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) {
1005       LM_ERR("Unable to extract allowed headers!!\n");
1006       goto error;
1007    }
1008    headers.s[headers.len]=0;
1009    /*let's get the body*/
1010    if(my_msg->content_length)
1011       clen=(long)get_content_length(my_msg);
1012    if(clen!=0){
1013       if(!(body.s=pkg_malloc(clen))){
1014 	 LM_ERR("Out of Memory!");
1015 	 goto error;
1016       }
1017       memcpy(body.s,get_body(my_msg),clen);
1018       body.len=clen;
1019       body.s[clen]=0;
1020       LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\
1021 	    body.len,body.len,body.s,headers.len,headers.len,headers.s);
1022       /*t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
1023    }else{
1024       body.s=NULL;
1025       body.len=0;
1026    }
1027    /*Now... create the UAC !!
1028     * it would be great to know the hash_index and the label that have been assigned
1029     * to our newly created cell, but t_uac does not leave any way for us to know...
1030     * only that when that transaction transitions its state (ie. a response is received,
1031     * a timeout is reached, etc...) the callback will be called with the given parameter.
1032     *
1033     * So the only way we have to know who we are, is passing as a parameter a structure with
1034     * 2 pointers: one to the app_server and the other, the identifier of the UAC (uac_id).
1035     *
1036     */
1037    if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
1038       LM_ERR("out of shared memory\n");
1039       goto error;
1040    }
1041    the_param->who=my_as;
1042    the_param->uac_id=uac_id;
1043    the_param->processor_id=processor_id;
1044    the_param->destroy_cb_set=0;
1045 
1046    shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri);
1047 
1048    if (my_msg->route) {
1049       if (parse_rr(my_msg->route) < 0) {
1050 	 LM_ERR( "Error while parsing Route body\n");
1051 	 goto error;
1052       }
1053       /* TODO route_set should be a shm copy of my_msg->route->parsed */
1054       my_dlg->route_set=(rr_t*)my_msg->route->parsed;
1055       /** this SHOULD be:
1056        shm_duplicate_rr(&my_dlg->route_set,my_msg->route->parsed);
1057        * but it will last more...
1058        */
1059    }
1060    calculate_hooks(my_dlg);
1061    if(flags & SPIRAL_FLAG){
1062       memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
1063       headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
1064       headers.s[headers.len]=0;
1065       fake_uri.s=pkg_malloc(200);
1066       fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);
1067 
1068       if(fake_uri.len<0){
1069 	 LM_ERR("printing local uri\n");
1070 	 goto error;
1071       }
1072       my_dlg->hooks.next_hop=&fake_uri;
1073    }
1074    /* Kamailio and OpenSIPs seem to have diverged quite a bit on flags and events
1075       notified to UACs. Let's see if kamailio gets it right by now, if not
1076       this is a TODO: check PASS_PROVISIONAL
1077       my_dlg->T_flags=T_NO_AUTO_ACK|T_PASS_PROVISIONAL_FLAG ;
1078       this is the same as (TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT) in Kamailio
1079    */
1080 
1081    set_uac_req(&uac_r, &(my_msg->first_line.u.request.method), &headers,
1082 		   &body, my_dlg,TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT, uac_cb,
1083 		   (void*)the_param);
1084 
1085    ret=seas_f.tmb.t_request_within(&uac_r);
1086 
1087    /** now undo all the fakes we have put in my_dlg*/
1088    /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/
1089    my_dlg->route_set=(rr_t *)0;
1090    if (ret < 0) {
1091       err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
1092       LM_ERR("failed to send the [%.*s] request\n",uac_r.method->len,uac_r.method->s);
1093       LM_ERR("Error on request_within %s\n",err_buf );
1094       if(err_ret > 0) {
1095 	 as_action_fail_resp(uac_id,ret,err_buf,0);
1096       }else{
1097 	 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
1098       }
1099       goto error;
1100    }
1101    retval=0;
1102    goto exit;
1103 error:
1104    retval = -1;
1105    if(the_param)
1106       shm_free(the_param);
1107 exit:
1108    seas_f.tmb.free_dlg(my_dlg);
1109    if(headers.s)
1110       pkg_free(headers.s);
1111    if(body.s)
1112       pkg_free(body.s);
1113    if(fake_uri.s)
1114       pkg_free(fake_uri.s);
1115    if(my_msg){
1116       if(my_msg->headers)
1117 	 free_hdr_field_lst(my_msg->headers);
1118       pkg_free(my_msg);
1119    }
1120    return retval;
1121 }
1122 
1123 /**
1124  * len MUST be >0
1125  */
print_local_uri(as_p as,char processor_id,char * where,int len)1126 int print_local_uri(as_p as,char processor_id,char *where,int len)
1127 {
1128    int i;
1129    struct socket_info *si;
1130    str proto;
1131    proto.s=NULL;
1132    proto.len=0;
1133    for(i=0;i<MAX_BINDS;i++){
1134       if(as->bound_processor[i]==processor_id)
1135 	 break;
1136    }
1137    if(i==MAX_BINDS){
1138       LM_DBG("processor ID not found\n");
1139       return -1;
1140    }
1141    si=as->binds[i];
1142    switch(si->proto){
1143       case PROTO_UDP:
1144 	 proto.s="";
1145 	 proto.len=0;
1146 	 break;
1147       case PROTO_TCP:
1148 	 proto.s=TRANSPORT_PARAM "TCP";
1149 	 proto.len=TRANSPORT_PARAM_LEN + 3;
1150 	 break;
1151       case PROTO_TLS:
1152 	 proto.s=TRANSPORT_PARAM "TLS";
1153 	 proto.len=TRANSPORT_PARAM_LEN + 3;
1154 	 break;
1155       case PROTO_SCTP:
1156 	 proto.s=TRANSPORT_PARAM "SCTP";
1157 	 proto.len=TRANSPORT_PARAM_LEN + 4;
1158 	 break;
1159       case PROTO_WS:
1160       case PROTO_WSS:
1161 	 proto.s=TRANSPORT_PARAM "WS";
1162 	 proto.len=TRANSPORT_PARAM_LEN + 2;
1163 	 break;
1164    }
1165    switch(si->address.af){
1166       case AF_INET:
1167 	 i=snprintf(where,len,"sip:%d.%d.%d.%d:%u%.*s",si->address.u.addr[0],si->address.u.addr[1],\
1168 	       si->address.u.addr[2],si->address.u.addr[3],si->port_no,proto.len,proto.s);
1169 	 break;
1170       case AF_INET6:
1171 	 i=snprintf(where,len,"sip:[%x:%x:%x:%x:%x:%x:%x:%x]:%u%.*s", htons(si->address.u.addr16[0]), htons(si->address.u.addr16[1]),\
1172 	       htons(si->address.u.addr16[2]), htons(si->address.u.addr16[3]), htons(si->address.u.addr16[4]), htons(si->address.u.addr16[5]),\
1173 	       htons(si->address.u.addr16[6]), htons(si->address.u.addr16[7]),si->port_no,proto.len,proto.s);
1174 	 break;
1175       default:
1176 	 LM_ERR("address family unknown\n");
1177 	 return -1;
1178    }
1179    if(i>len){
1180       LM_ERR("Output was truncated!!\n");
1181       return -1;
1182    }else if(i<0){
1183       LM_ERR("Error on snprintf\n");
1184       return i;
1185    }
1186    return i;
1187 }
1188 
1189 /* !!! COPIED FROM MODULES/TM  !!
1190  * This function skips name part
1191  * uri parsed by parse_contact must be used
1192  * (the uri must not contain any leading or
1193  *  trailing part and if angle bracket were
1194  *  used, right angle bracket must be the
1195  *  last character in the string)
1196  *
1197  * _s will be modified so it should be a tmp
1198  * copy
1199  */
get_raw_uri(str * _s)1200 void get_raw_uri(str* _s)
1201 {
1202         char* aq;
1203 
1204         if (_s->s[_s->len - 1] == '>') {
1205                 aq = find_not_quoted(_s, '<');
1206                 _s->len -= aq - _s->s + 2;
1207                 _s->s = aq + 1;
1208         }
1209 }
1210 /* !!! COPIED FROM MODULES/TM  !!
1211  * Calculate dialog hooks
1212  *
1213  * This is copied from modules/tm/dlg.c
1214  *
1215  * Maybe a reference to the original function in TM
1216  * could be reached via handlers or whatever...
1217  */
calculate_hooks(dlg_t * _d)1218 static inline int calculate_hooks(dlg_t* _d)
1219 {
1220    str* uri;
1221    struct sip_uri puri;
1222 
1223    if (_d->route_set) {
1224       uri = &_d->route_set->nameaddr.uri;
1225       if (parse_uri(uri->s, uri->len, &puri) < 0) {
1226          LM_ERR( "Error while parsing URI\n");
1227          return -1;
1228       }
1229 
1230       if (puri.lr.s) {
1231          if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
1232          else _d->hooks.request_uri = &_d->rem_uri;
1233 	 _d->hooks.next_hop = &_d->route_set->nameaddr.uri;
1234 	 _d->hooks.first_route = _d->route_set;
1235       } else {
1236          _d->hooks.request_uri = &_d->route_set->nameaddr.uri;
1237          _d->hooks.next_hop = _d->hooks.request_uri;
1238          _d->hooks.first_route = _d->route_set->next;
1239          _d->hooks.last_route = &_d->rem_target;
1240       }
1241    } else {
1242       if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
1243       else _d->hooks.request_uri = &_d->rem_uri;
1244       _d->hooks.next_hop = _d->hooks.request_uri;
1245    }
1246 
1247    if ((_d->hooks.request_uri) && (_d->hooks.request_uri->s) && (_d->hooks.request_uri->len)) {
1248       _d->hooks.ru.s = _d->hooks.request_uri->s;
1249       _d->hooks.ru.len = _d->hooks.request_uri->len;
1250       _d->hooks.request_uri = &_d->hooks.ru;
1251       get_raw_uri(_d->hooks.request_uri);
1252    }
1253    if ((_d->hooks.next_hop) && (_d->hooks.next_hop->s) && (_d->hooks.next_hop->len)) {
1254       _d->hooks.nh.s = _d->hooks.next_hop->s;
1255       _d->hooks.nh.len = _d->hooks.next_hop->len;
1256       _d->hooks.next_hop = &_d->hooks.nh;
1257       get_raw_uri(_d->hooks.next_hop);
1258    }
1259 
1260    return 0;
1261 }
1262 
1263 /**
1264  * Strips the "<strip_top_vias>" topmost via headers.
1265  * Leaves only the topmost "<allow_top_routes>" Record-Route headers.
1266  *
1267  */
extract_allowed_headers(struct sip_msg * my_msg,int strip_top_vias,int allow_top_Rroutes,hdr_flags_t forbidden_hdrs,char * headers,int headers_len)1268 int extract_allowed_headers(struct sip_msg *my_msg,int strip_top_vias,int allow_top_Rroutes,hdr_flags_t forbidden_hdrs,char *headers,int headers_len)
1269 {
1270    struct hdr_field *hf;
1271    rr_t *rb;
1272    struct via_body *vb;
1273    int len,k,rtcnt,i;
1274 
1275    len=0;
1276    rtcnt=allow_top_Rroutes;
1277    rb=NULL;
1278    vb=NULL;
1279 
1280    for(hf=my_msg->headers;hf;hf=hf->next){
1281       if(forbidden_hdrs & HDR_T2F(hf->type)){
1282 	 LM_DBG("Skipping header (%.*s)\n",hf->name.len,hf->name.s);
1283 	 continue;
1284       }else if(hf->type==HDR_VIA_T && strip_top_vias > 0){
1285 	 /** All vias MUST be parsed !!*/
1286 	 for(i=0,vb=hf->parsed;vb;vb=vb->next,i++);
1287 	 if(i<=strip_top_vias){
1288 	    LM_DBG("Stripping vias [%.*s]\n",hf->len,hf->name.s);
1289 	    /** skip this via header*/
1290 	    strip_top_vias-=i;
1291 	 }else{
1292 	    assert(i>1);
1293 	    vb=hf->parsed;
1294 	    while(strip_top_vias--)
1295 	       vb=vb->next;
1296 	    k= (hf->name.s + hf->len) - vb->name.s;
1297 	    LM_DBG("Stripping vias [%.*s]\n",(int)(vb->name.s-hf->name.s),
1298 		  hf->name.s);
1299 	    if(k+VIA_LEN<headers_len){
1300 	       memcpy(headers+len,VIA,VIA_LEN);
1301 	       len+=VIA_LEN;
1302 	       memcpy(headers+len,vb->name.s,k);
1303 	       len+=k;
1304 	    }else{
1305 	       LM_ERR("Out Of Space !!\n");
1306 	       goto error;
1307 	    }
1308 	 }
1309       }else if(hf->type==HDR_RECORDROUTE_T && rtcnt>=0){
1310 	 if(rtcnt==0)
1311 	    continue;
1312 	 if(!hf->parsed && 0>parse_rr(hf)){
1313 	    LM_ERR("parsing Record-Route:\"%.*s\"\n",hf->body.len,hf->body.s);
1314 	    goto error;
1315 	 }
1316 	 for(i=0,rb=hf->parsed;rb;rb=rb->next,i++);
1317 	 if(i<=rtcnt){
1318 	    if((len+hf->len)<headers_len){
1319 	       LM_DBG("Allowing RecordRoute [%.*s]\n",hf->len,hf->name.s);
1320 	       memcpy(headers+len,hf->name.s,hf->len);
1321 	       len+=hf->len;
1322 	    }else{
1323 	       LM_ERR("Unable to keep recordroute (not enough space left in headers) Discarding \"%.*s\" \n",hf->name.len,hf->name.s);
1324 	       goto error;
1325 	    }
1326 	    /** is this dangerous ? because the rtcnt is the control variable for this conditional 'if'
1327 	     * so if I change rtcnt value in one of the statements... what then ??? */
1328 	    rtcnt-=i;
1329 	 }else{
1330 	    assert(rtcnt>0);
1331 	    rb=hf->parsed;
1332 	    while(rb && --rtcnt)
1333 	       rb=rb->next;
1334 		if(!rb) {
1335 			LM_ERR("no rr\n");
1336 			goto error;
1337 		}
1338 	    k= (((rb->nameaddr.name.s) + rb->len)-hf->name.s) ;
1339 	    if(len+k+CRLF_LEN<headers_len){
1340 	       memcpy(headers+len,hf->name.s,k);
1341 	       LM_DBG("Allowing RecordRoute [%.*s\r\n]\n",k,hf->name.s);
1342 	       len+=k;
1343 	       memcpy(headers+len,CRLF,CRLF_LEN);
1344 	       len+=CRLF_LEN;
1345 	    }else{
1346 	       LM_ERR("Out Of Space !!\n");
1347 	       goto error;
1348 	    }
1349 	 }
1350 	 if(hf->parsed){
1351 	    free_rr((rr_t **)(void*)(&hf->parsed));
1352 	    hf->parsed=NULL;
1353 	 }
1354       }else{
1355 	 if((len+hf->len)<headers_len){
1356 	    memcpy(headers+len,hf->name.s,hf->len);
1357 	    len+=hf->len;
1358 	 }else{
1359 	    LM_WARN("Too many headers. Discarding \"%.*s\" \n",
1360 				hf->name.len,hf->name.s);
1361 	 }
1362       }
1363    }/*for*/
1364    return len;
1365 error:
1366    return -1;
1367 }
1368 
1369 
1370 /**
1371  * ERROR action responses are composed of:
1372  * 4: the length of the event
1373  * 1: the event type (AC_RES_FAIL)
1374  * 4: NBO of the uac-action-request identification (uac_id)
1375  * 4: the sip_error code in NBO.
1376  * 1: (unsigned) the length of the string.
1377  * N: the string
1378  *
1379  */
as_action_fail_resp(int uac_id,int sip_error,char * err_buf,int i)1380 int as_action_fail_resp(int uac_id,int sip_error,char *err_buf,int i)
1381 {
1382    char msg[14+MAX_REASON_LEN];
1383    int k, ev_len;
1384    k=4;
1385    if(i==0)
1386       i=strlen(err_buf);
1387    if(i>MAX_REASON_LEN){
1388       LM_ERR("Error Reason bigger than MAX_REASON_LEN\n");
1389       return -1;
1390    }
1391    msg[k++]=AC_RES_FAIL;
1392    uac_id=htonl(uac_id);
1393    memcpy(msg+k,&uac_id,4);
1394    k+=4;
1395    sip_error=htonl(sip_error);
1396    memcpy(msg+k,&sip_error,4);
1397    k+=4;
1398    msg[k++]=(char)(unsigned char)i;
1399    memcpy(msg+k,err_buf,i);
1400    k+=i;
1401    ev_len=htonl(k);
1402    memcpy(msg,&ev_len,4);
1403    if(write(my_as->u.as.action_fd,msg,k)<=0){
1404       LM_DBG("Ignoring error write\n");
1405    }
1406    return 0;
1407 }
1408 
1409 /*
1410  * This callback function should be used in order to free the parameters passed to uac_cb.
1411  * This callback is called when the transaction is detroyed.
1412  */
uac_cleanup_cb(struct cell * t,int type,struct tmcb_params * rcvd_params)1413 void uac_cleanup_cb(struct cell* t, int type, struct tmcb_params *rcvd_params)
1414 {
1415 	struct as_uac_param *ev_info;
1416 
1417 	ev_info=(struct as_uac_param*)*rcvd_params->param;
1418 
1419 	if(ev_info) {
1420 		shm_free(ev_info);
1421 		*rcvd_params->param=NULL;
1422 	}
1423 }
1424 
uas_e2e_ack_cb(struct cell * t,int type,struct tmcb_params * rcvd_params)1425 void uas_e2e_ack_cb(struct cell* t, int type,struct tmcb_params *rcvd_params)
1426 {
1427    struct as_uac_param *ev_info;
1428    int mylen;
1429    as_msg_p my_as_ev=NULL;
1430    char *buffer=NULL;
1431 
1432    ev_info=(struct as_uac_param*)*rcvd_params->param;
1433 
1434    if(!(type & TMCB_E2EACK_IN))
1435       return;
1436 
1437    if(!(my_as_ev=shm_malloc(sizeof(as_msg_t)))){
1438       LM_ERR("no more shared mem\n");
1439       goto error;
1440    }
1441    if(!(buffer=create_as_event_t(t,rcvd_params->req,ev_info->processor_id,&mylen,E2E_ACK))){
1442       LM_ERR("unable to create event code\n");
1443       goto error;
1444    }
1445    my_as_ev->as = ev_info->who;
1446    my_as_ev->msg = buffer;
1447    my_as_ev->len = mylen;
1448    my_as_ev->type = RES_IN;
1449    my_as_ev->transaction = t;
1450    if(write(write_pipe,&my_as_ev,sizeof(as_msg_p))<=0){
1451       goto error;
1452    }
1453    goto exit;
1454 error:
1455    if(my_as_ev){
1456       shm_free(my_as_ev);
1457    }
1458    if(buffer)
1459       shm_free(buffer);
1460 exit:
1461    return ;
1462 }
1463 
1464 /**
1465  * This function will be called from a SER process when a reply is received for
1466  * the transaction. The SER processes only have acces to the EventDispatcher
1467  * fifo (not to the ActionDispatcher) so EventDispatcher will be the one who
1468  * will send the event to the AppServer.
1469  */
uac_cb(struct cell * t,int type,struct tmcb_params * rcvd_params)1470 void uac_cb(struct cell* t, int type,struct tmcb_params *rcvd_params)
1471 {
1472    as_msg_p my_as_ev=0;
1473    int mylen,code,i;
1474    struct as_uac_param *ev_info;
1475    char *buffer;
1476 
1477    ev_info=(struct as_uac_param*)*rcvd_params->param;
1478    code=rcvd_params->code;
1479    buffer=0;
1480    if(!ev_info || !ev_info->who){
1481       return;
1482    }
1483 
1484    if(type == TMCB_LOCAL_COMPLETED && !ev_info->destroy_cb_set) {
1485       if(seas_f.tmb.register_tmcb(NULL, t, TMCB_DESTROY , uac_cleanup_cb, (void*)ev_info, 0) <= 0) {
1486          LM_ERR( "register_tmcb for destroy callback failed\n");
1487          goto error;
1488       }
1489       ev_info->destroy_cb_set = 1;
1490    }
1491 
1492    LM_DBG("reply to UAC Transaction for AS:%.*s code: %d\n",
1493 		   ev_info->who->name.len,ev_info->who->name.s,code);
1494    LM_DBG("transaction %p Nr_of_outgoings:%d is_Local:%c\n",
1495 		   t,t->nr_of_outgoings,is_local(t)?'y':'n');
1496    for(i=0;i<t->nr_of_outgoings;i++)
1497       LM_DBG("UAC[%d].last_received=%d\n",i,t->uac[i].last_received);
1498    if(!(my_as_ev=shm_malloc(sizeof(as_msg_t)))){
1499       LM_ERR("no more shared mem\n");
1500       goto error;
1501    }
1502    if(!(buffer=create_as_action_reply(t,rcvd_params,ev_info->uac_id,ev_info->processor_id,&mylen))){
1503       LM_ERR("failed to encode message\n");
1504       goto error;
1505    }
1506    my_as_ev->as = ev_info->who;
1507    my_as_ev->msg = buffer;
1508    my_as_ev->len = mylen;
1509    my_as_ev->type = RES_IN;
1510    my_as_ev->transaction = t;
1511    if(write(write_pipe,&my_as_ev,sizeof(as_msg_p))<=0){
1512       goto error;
1513    }
1514    goto exit;
1515 error:
1516    if(my_as_ev){
1517       shm_free(my_as_ev);
1518    }
1519    if(buffer)
1520       shm_free(buffer);
1521 exit:
1522    return ;
1523 }
1524 
create_as_action_reply(struct cell * c,struct tmcb_params * params,int uac_id,char processor_id,int * evt_len)1525 char* create_as_action_reply(struct cell *c,struct tmcb_params *params,int uac_id,char processor_id,int *evt_len)
1526 {
1527    int i;
1528    unsigned int code,flags;
1529    unsigned short int port;
1530    unsigned int k,len;
1531    char *buffer;
1532    struct sip_msg *msg;
1533    if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
1534       LM_ERR("create_as_action_reply Out Of Memory !!\n");
1535       return 0;
1536    }
1537    msg=0;
1538    *evt_len=0;
1539    flags=0;
1540    if(params->rpl==FAKED_REPLY)
1541       flags=FAKED_REPLY_FLAG;
1542    /*length*/
1543    k=4;
1544    /*type*/
1545    buffer[k++]=(unsigned char)RES_IN;
1546    /*processor id*/
1547    buffer[k++]=processor_id;
1548    /*flags (by now, not used)*/
1549    flags=htonl(flags);
1550    memcpy(buffer+k,&flags,4);
1551    k+=4;
1552    /*recv info*/
1553    if(!(params->rpl == FAKED_REPLY)) {
1554       msg=params->rpl;
1555       /*protocol should be UDP,TCP,TLS or whatever*/
1556       buffer[k++]=(unsigned char)msg->rcv.proto;
1557       /*src ip len + src ip*/
1558       len=msg->rcv.src_ip.len;
1559       buffer[k++]=(unsigned char)len;
1560       memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
1561       k+=len;
1562       /*dst ip len + dst ip*/
1563       len=msg->rcv.dst_ip.len;
1564       buffer[k++]=(unsigned char)len;
1565       memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
1566       k+=len;
1567       /*src port */
1568       port=htons(msg->rcv.src_port);
1569       memcpy(buffer+k,&port,2);
1570       k+=2;
1571       /*dst port */
1572       port=htons(msg->rcv.dst_port);
1573       memcpy(buffer+k,&port,2);
1574       k+=2;
1575    }else{
1576       /*protocol*/
1577       buffer[k++]=0;
1578       /*src ip len*/
1579       buffer[k++]=0;
1580       /*dst ip len*/
1581       buffer[k++]=0;
1582       /*skip src port and dst port*/
1583       buffer[k++]=0;
1584       buffer[k++]=0;
1585       buffer[k++]=0;
1586       buffer[k++]=0;
1587    }
1588    /*hash_index*/
1589    i=htonl(c->hash_index);
1590    memcpy(buffer+k,&i,4);
1591    k+=4;
1592    /*label*/
1593    i=(!strncmp(c->method.s,"CANCEL",6)) ? \
1594      htonl(((struct as_uac_param*)*params->param)->label) : \
1595 	htonl(c->label);
1596    memcpy(buffer+k,&i,4);
1597    k+=4;
1598    /*uac_id*/
1599    uac_id=htonl(uac_id);
1600    memcpy(buffer+k,&uac_id,4);
1601    k+=4;
1602    /*code*/
1603    code=htonl(params->code);
1604    memcpy(buffer+k,&code,4);
1605    k+=4;
1606    /*length of event (hdr+payload-4), copied at the beginning*/
1607    if(params->rpl != FAKED_REPLY) {
1608       if((i=encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k))<0){
1609 	 LM_ERR("failed to encode msg\n");
1610 	 goto error;
1611       }
1612       k+=i;
1613    }
1614    *evt_len=k;
1615    k=htonl(k);
1616    memcpy(buffer,&k,4);
1617    return buffer;
1618 error:
1619    return 0;
1620 }
1621 
1622 
1623