00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <arpa/inet.h>
00031 #include <sys/types.h>
00032 #include <signal.h>
00033 #include <poll.h>
00034 #include <assert.h>
00035
00036 #include "../../mem/mem.h"
00037 #include "../../dprint.h"
00038 #include "../../str.h"
00039 #include "../../pt.h"
00040 #include "../../ip_addr.h"
00041 #include "../../tags.h"
00042 #include "../../error.h"
00043 #include "../../ut.h"
00044 #include "../../parser/hf.h"
00045 #include "../../parser/parse_fline.h"
00046 #include "../../parser/parser_f.h"
00047 #include "../../parser/parse_to.h"
00048 #include "../../parser/parse_from.h"
00049 #include "../../parser/parse_cseq.h"
00050 #include "../../parser/parse_content.h"
00051 #include "../../parser/parse_rr.h"
00052 #include "../../parser/parse_via.h"
00053 #include "../../parser/parse_param.h"
00054 #include "../../parser/parse_uri.h"
00055 #include "../../parser/msg_parser.h"
00056 #include "encode_msg.h"
00057 #include "../tm/t_lookup.h"
00058 #include "../tm/h_table.h"
00059 #include "../tm/dlg.h"
00060 #include "seas.h"
00061 #include "statistics.h"
00062 #include "seas_action.h"
00063 #include "seas_error.h"
00064 #include "ha.h"
00065
00066 #define MAX_HEADER 1024
00067
00068 #define SPIRAL_HDR "X-WeSIP-SPIRAL: true"
00069 #define SPIRAL_HDR_LEN (sizeof(SPIRAL_HDR)-1)
00070
00071 #define RECORD_ROUTE "Record-Route: "
00072 #define RECORD_ROUTE_LEN (sizeof(RECORD_ROUTE)-1)
00073
00074 #define VIA "Via: "
00075 #define VIA_LEN (sizeof(VIA)-1)
00076
00077 extern char *seas_tag_suffix;
00078 extern char seas_tags[];
00079 pid_t my_parent;
00080 extern int fifo_pid;
00081
00082 static inline struct sip_msg *parse_ac_msg(hdr_flags_t flags,char *start,int len);
00083 static inline void free_sip_msg_lite(struct sip_msg *my_msg);
00084 static inline int calculate_hooks(dlg_t* _d);
00085
00086 static inline int process_input(int fd);
00087 static inline int process_pings(struct ha *the_table);
00088 static inline int ac_jain_pong(as_p the_as,char *action,int len);
00089 int process_pong(struct ha *the_table,unsigned int seqno);
00090 int print_local_uri(as_p as,char processor_id,char *where,int len);
00091
00092
00093 int dispatch_actions(void)
00094 {
00095 int fd,n,ret,timeout,elapsed_ms;
00096 static int ktimeout;
00097 struct pollfd fds[1];
00098 struct timeval last,now;
00099
00100
00101
00102 pt=0;
00103 fd=my_as->u.as.action_fd;
00104 fds[0].fd=fd;
00105 fds[0].events=POLLIN|POLLHUP;
00106 fds[0].revents=0;
00107 my_parent=getppid();
00108 snprintf(whoami,MAX_WHOAMI_LEN,"[%.*s] Action dispatcher",my_as->name.len,my_as->name.s);
00109 if(jain_ping_timeout && servlet_ping_timeout)
00110 ktimeout=jain_ping_timeout<servlet_ping_timeout?jain_ping_timeout:servlet_ping_timeout;
00111 else if(jain_ping_timeout)
00112 ktimeout=jain_ping_timeout;
00113 else if(servlet_ping_timeout)
00114 ktimeout=servlet_ping_timeout;
00115
00116 if((my_as->u.as.ac_buffer.s = pkg_malloc(AS_BUF_SIZE))==0){
00117 LM_ERR("no more pkg mem\n");
00118 return -1;
00119 }
00120 my_as->u.as.ac_buffer.len=0;
00121 if(use_ha){
00122 timeout=ktimeout;
00123 while(1){
00124 gettimeofday(&last,NULL);
00125 print_pingtable(&my_as->u.as.jain_pings,-1,1);
00126 if(0>(n=poll(fds,1,timeout))){
00127 if(errno==EINTR){
00128 gettimeofday(&last,NULL);
00129 continue;
00130 }else if(errno==EBADF){
00131 LM_ERR("EBADF !!\n");
00132 }else{
00133 LM_ERR("on poll\n");
00134 }
00135 }else if(n==0){
00136 if (0>(ret=process_pings(&my_as->u.as.jain_pings))) {
00137 return ret;
00138 }
00139 timeout=ktimeout;
00140 }else{
00141 if (0>(ret=process_input(fd))) {
00142 return ret;
00143 }
00144 gettimeofday(&now,NULL);
00145 elapsed_ms=((now.tv_sec-last.tv_sec)*1000)+((now.tv_usec-last.tv_usec)/1000);
00146 if(elapsed_ms<timeout){
00147 timeout-=elapsed_ms;
00148 }else{
00149 if(0>(ret=process_pings(&my_as->u.as.jain_pings))){
00150 return ret;
00151 }
00152 timeout=ktimeout;
00153 }
00154 }
00155 fds[0].events=POLLIN|POLLHUP;
00156 fds[0].revents=0;
00157 }
00158 }else{
00159 do{
00160 ret=process_input(fd);
00161 }while(ret>=0);
00162 }
00163
00164 return 0;
00165 }
00166
00167 static inline int process_input(int fd)
00168 {
00169 int j,k;
00170
00171 k=AS_BUF_SIZE-(my_as->u.as.ac_buffer.len);
00172 again:
00173 if(0>(j=read(fd,my_as->u.as.ac_buffer.s+my_as->u.as.ac_buffer.len,k))){
00174 if(errno==EINTR)
00175 goto again;
00176 LM_ERR("reading data for as %.*s (%s)\n",my_as->name.len,my_as->name.s,strerror(errno));
00177 return -1;
00178 }else if(j==0){
00179 pkg_free(my_as->u.as.ac_buffer.s);
00180 close(fd);
00181 LM_ERR("read 0 bytes from AS:%.*s\n",my_as->name.len,my_as->name.s);
00182
00183
00184
00185
00186 return -2;
00187 }
00188 (my_as->u.as.ac_buffer.len)+=j;
00189 LM_DBG("read %d bytes from AS action socket (total = %d)\n",j,my_as->u.as.ac_buffer.len);
00190 if(use_stats)
00191 receivedplus();
00192 if(my_as->u.as.ac_buffer.len>5){
00193 process_action(&my_as->u.as);
00194 LM_DBG("(Action dispatched,buffer.len=%d)\n",my_as->u.as.ac_buffer.len);
00195 }
00196 return 0;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 static inline int process_pings(struct ha *the_table)
00214 {
00215 int i,k,elapsed;
00216 struct ping *tmp;
00217 struct timeval now;
00218
00219 tmp=NULL;
00220 gettimeofday(&now,NULL);
00221 if(the_table->count==0)
00222 return 0;
00223 lock_get(the_table->mutex);
00224 {
00225 print_pingtable(the_table,-1,0);
00226 for(i=0;i<the_table->count;i++){
00227 k=(the_table->begin+i)%the_table->size;
00228 tmp=the_table->pings+k;
00229 elapsed=(now.tv_sec-tmp->sent.tv_sec)*1000+(now.tv_usec-tmp->sent.tv_usec)/1000;
00230 if(elapsed>the_table->timeout){
00231 LM_DBG("ping timed out %d\n",tmp->id);
00232 the_table->timed_out_pings++;
00233 }else{
00234 the_table->begin=k;
00235 the_table->count-=i;
00236 break;
00237 }
00238 }
00239 }
00240 lock_release(the_table->mutex);
00241 return 0;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 int process_action(as_p the_as)
00277 {
00278 unsigned int ac_len;
00279 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);
00280
00281
00282
00283 if(use_stats)
00284 stats_reply();
00285 if(ac_len>AS_BUF_SIZE){
00286 LM_WARN("action too big (%d)!!! should be skipped and"
00287 " an error returned!\n",ac_len);
00288 return -1;
00289 }
00290 while (the_as->ac_buffer.len>=ac_len) {
00291 LM_DBG("Processing action %d bytes long\n",ac_len);
00292 switch(the_as->ac_buffer.s[4]){
00293 case REPLY_PROV:
00294 case REPLY_FIN:
00295 LM_DBG("Processing a REPLY action from AS (length=%d): %.*s\n",
00296 ac_len,the_as->name.len,the_as->name.s);
00297 ac_reply(the_as,the_as->ac_buffer.s+5,ac_len-5);
00298 break;
00299 case UAC_REQ:
00300 LM_DBG("Processing an UAC REQUEST action from AS (length=%d): %.*s\n",
00301 ac_len,the_as->name.len,the_as->name.s);
00302 ac_uac_req(the_as,the_as->ac_buffer.s+5,ac_len-5);
00303 break;
00304 case AC_CANCEL:
00305 LM_DBG("Processing a CANCEL REQUEST action from AS (length=%d): %.*s\n",
00306 ac_len,the_as->name.len,the_as->name.s);
00307 ac_cancel(the_as,the_as->ac_buffer.s+5,ac_len-5);
00308 break;
00309 case SL_MSG:
00310 LM_DBG("Processing a STATELESS MESSAGE action from AS (length=%d): %.*s\n",
00311 ac_len,the_as->name.len,the_as->name.s);
00312 ac_sl_msg(the_as,the_as->ac_buffer.s+5,ac_len-5);
00313 break;
00314 case JAIN_PONG:
00315 LM_DBG("Processing a PONG\n");
00316 ac_jain_pong(the_as,the_as->ac_buffer.s+5,ac_len-5);
00317 break;
00318 default:
00319 LM_DBG("Processing a UNKNOWN TYPE action from AS (length=%d): %.*s\n",
00320 ac_len,the_as->name.len,the_as->name.s);
00321 break;
00322 }
00323 memmove(the_as->ac_buffer.s,the_as->ac_buffer.s+ac_len,(the_as->ac_buffer.len)-ac_len);
00324 (the_as->ac_buffer.len)-=ac_len;
00325 if(the_as->ac_buffer.len>5){
00326 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);
00327 }else{
00328 return 0;
00329 }
00330 }
00331 return 0;
00332 }
00333
00334 static inline int ac_jain_pong(as_p the_as,char *action,int len)
00335 {
00336 unsigned int seqno,flags;
00337 int k;
00338 k=0;
00339 net2hostL(flags,action,k);
00340 net2hostL(seqno,action,k);
00341 process_pong(&the_as->jain_pings,seqno);
00342 return 0;
00343 }
00344
00345 int process_pong(struct ha *the_table,unsigned int seqno)
00346 {
00347 int i,k,elapsed;
00348 struct ping *tmp;
00349 struct timeval now;
00350
00351 gettimeofday(&now,NULL);
00352 tmp=NULL;
00353 if(the_table->count==0)
00354 return 0;
00355 lock_get(the_table->mutex);
00356 print_pingtable(the_table,-1,0);
00357 for(i=0;i<the_table->count;i++){
00358 k=(the_table->begin+i)%the_table->size;
00359 tmp=the_table->pings+k;
00360 if(tmp->id == seqno){
00361 elapsed=(now.tv_sec-tmp->sent.tv_sec)*1000+(now.tv_usec-tmp->sent.tv_usec)/1000;
00362 LM_DBG("Ping-Pong delay: %d (timeout was:%d)\n",elapsed,the_table->timeout);
00363 if(elapsed>the_table->timeout){
00364
00365
00366 the_table->timed_out_pings+=i;
00367 }
00368
00369 the_table->count-=(i+1);
00370 the_table->begin=(k+1)%the_table->size;
00371 break;
00372 }
00373 }
00374 lock_release(the_table->mutex);
00375 return 0;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 int ac_cancel(as_p the_as,char *action,int len)
00394 {
00395 unsigned int flags,ret,cancelled_hashIdx,cancelled_label,i;
00396 char processor_id;
00397 struct sip_msg *my_msg;
00398 struct as_uac_param *the_param;
00399 struct cell* t_invite;
00400 int k,retval,uac_id;
00401 str headers,body;
00402
00403 body.s=headers.s=NULL;
00404 my_msg=NULL;
00405 the_param=NULL;
00406 i=k=0;
00407
00408 net2hostL(flags,action,k);
00409 net2hostL(uac_id,action,k);
00410
00411 processor_id=action[k++];
00412
00413 net2hostL(cancelled_hashIdx,action,k);
00414 net2hostL(cancelled_label,action,k);
00415
00416 if(!(headers.s=pkg_malloc(MAX_HEADER))){
00417 LM_ERR("Out of Memory!!");
00418 goto error;
00419 }
00420 headers.len=0;
00421 if(!(my_msg=pkg_malloc(sizeof(struct sip_msg)))){
00422 LM_ERR("out of memory!\n");
00423 goto error;
00424 }
00425 memset(my_msg,0,sizeof(struct sip_msg));
00426 my_msg->buf=action+k;
00427 my_msg->len=len-k;
00428 LM_DBG("Action UAC Message: uac_id:%d processor_id=%d, message:[%.*s]\n",
00429 uac_id,processor_id,len-4,&action[4]);
00430 if(parse_msg(action+k,len-k,my_msg)<0){
00431 LM_ERR("parsing sip_msg");
00432 goto error;
00433 }
00434 if(my_msg->first_line.type==SIP_REPLY){
00435 LM_ERR("trying to create a UAC with a SIP response!!\n");
00436 goto error;
00437 }
00438 if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
00439 LM_ERR("parsing headers\n");
00440 goto error;
00441 }
00442 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))) {
00443 LM_ERR("Unable to extract allowed headers!!\n");
00444 goto error;
00445 }
00446 if(flags & SPIRAL_FLAG){
00447 memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
00448 headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 }
00459
00460 headers.s[headers.len]=0;
00461
00462
00463 i=(unsigned int)get_content_length(my_msg);
00464 if(i!=0){
00465 if(!(body.s=pkg_malloc(i))){
00466 LM_ERR("Out of Memory!");
00467 goto error;
00468 }
00469 memcpy(body.s,get_body(my_msg),i);
00470 body.len=i;
00471 LM_DBG("Trying to construct a Sip Request with: body:%d[%s]"
00472 " headers:%d[%s]\n", body.len,body.s,headers.len,headers.s);
00473 }else{
00474 body.s=NULL;
00475 body.len=0;
00476 }
00477
00478 if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
00479 LM_ERR("no more share memory\n");
00480 goto error;
00481 }
00482
00483 if(seas_f.tmb.t_lookup_ident(&t_invite,cancelled_hashIdx,cancelled_label)<0){
00484 LM_ERR("failed to t_lookup_ident hash_idx=%d,"
00485 "label=%d\n", cancelled_hashIdx,cancelled_label);
00486 goto error;
00487 }
00488 seas_f.tmb.unref_cell(t_invite);
00489
00490 the_param->who=my_as;
00491 the_param->uac_id=uac_id;
00492 the_param->processor_id=processor_id;
00493 the_param->destroy_cb_set=0;
00494
00495 ret=seas_f.tmb.t_cancel_uac(&headers,&body,cancelled_hashIdx,cancelled_label,uac_cb,(void*)the_param);
00496 if (ret == 0) {
00497 LM_ERR( "t_cancel_uac failed\n");
00498 as_action_fail_resp(uac_id,SE_CANCEL,SE_CANCEL_MSG,SE_CANCEL_MSG_LEN);
00499 goto error;
00500 }else{
00501 the_param->label=ret;
00502 }
00503
00504 seas_f.tmb.unref_cell(t_invite);
00505 retval=0;
00506 goto exit;
00507 error:
00508 retval = -1;
00509 if(the_param)
00510 shm_free(the_param);
00511 exit:
00512 if(headers.s)
00513 pkg_free(headers.s);
00514 if(body.s)
00515 pkg_free(headers.s);
00516 if(my_msg){
00517 if(my_msg->headers)
00518 free_hdr_field_lst(my_msg->headers);
00519 pkg_free(my_msg);
00520 }
00521 return retval;
00522 }
00523
00524 int recordroute_diff(struct sip_msg *req,struct sip_msg *resp)
00525 {
00526 struct hdr_field *hf;
00527 rr_t *rr1;
00528 int i,j,k;
00529 i=j=k=0;
00530
00531
00532
00533
00534 for(hf=resp->headers;hf;hf=hf->next,j=0){
00535 if(hf->type != HDR_RECORDROUTE_T)
00536 continue;
00537 if(!hf->parsed){
00538 if(0>parse_rr(hf))
00539 goto error;
00540 j=1;
00541 }
00542 for(rr1=hf->parsed;rr1;rr1=rr1->next){
00543 i++;
00544 }
00545 if(j){
00546 free_rr((rr_t**)(void*)&hf->parsed);
00547 hf->parsed=NULL;
00548 }
00549 }
00550
00551
00552
00553 for(hf=req->headers;hf;hf=hf->next,j=0){
00554 if(hf->type != HDR_RECORDROUTE_T)
00555 continue;
00556 if(!hf->parsed){
00557 if(0>parse_rr(hf))
00558 goto error;
00559 j=1;
00560 }
00561 for(rr1=hf->parsed;rr1;rr1=rr1->next){
00562 k++;
00563 }
00564 if(j){
00565 free_rr((rr_t**)(void*)&hf->parsed);
00566 hf->parsed=NULL;
00567 }
00568 }
00569 return i-k;
00570 error:
00571 return -1;
00572 }
00573
00574 int via_diff(struct sip_msg *req,struct sip_msg *resp)
00575 {
00576 struct hdr_field *hf;
00577 struct via_body *vb;
00578 int i,j,k;
00579
00580 i=j=k=0;
00581
00582 for(hf=resp->h_via1;hf;hf=hf->sibling){
00583 if(!hf->parsed){
00584 if((vb=pkg_malloc(sizeof(struct via_body)))==0){
00585 LM_ERR("Out of mem in via_diff!!\n");
00586 return -1;
00587 }
00588 memset(vb,0,sizeof(struct via_body));
00589 if(parse_via(hf->body.s,hf->body.s+hf->body.len+1,vb)==0){
00590 LM_ERR("Unable to parse via in via_diff!\n");
00591 pkg_free(vb);
00592 return -1;
00593 }
00594 hf->parsed=vb;
00595 j=1;
00596 }
00597 for(vb=hf->parsed;vb;vb=vb->next){
00598 i++;
00599 }
00600 if(j){
00601 free_via_list((struct via_body*)hf->parsed);
00602 hf->parsed=NULL;
00603 j=0;
00604 }
00605 }
00606 j=0;
00607
00608 for(hf=req->h_via1;hf;hf=hf->sibling){
00609 if(!hf->parsed){
00610 if((vb=pkg_malloc(sizeof(struct via_body)))==0){
00611 goto error;
00612 }
00613 memset(vb,0,sizeof(struct via_body));
00614 if(parse_via(hf->body.s,hf->body.s+hf->body.len+1,vb)==0){
00615 goto error;
00616 }
00617 hf->parsed=vb;
00618 j=1;
00619 }
00620 for(vb=hf->parsed;vb;vb=vb->next){
00621 k++;
00622 }
00623 if(j){
00624 free_via_list((struct via_body*)hf->parsed);
00625 hf->parsed=NULL;
00626 j=0;
00627 }
00628 }
00629 return i-k;
00630 error:
00631 return -1;
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 int ac_reply(as_p the_as,char *action,int len)
00645 {
00646 unsigned int flags,hash_index,label,contentlength;
00647 struct cell *c;
00648 struct sip_msg *my_msg;
00649 struct to_body *tb;
00650 str new_header,body,totag;
00651 char *ttag;
00652 int i,k,retval;
00653 static char headers[MAX_HEADER];
00654
00655 contentlength=0;
00656 ttag=NULL;
00657 my_msg=NULL;
00658 i=k=0;
00659
00660 net2hostL(flags,action,k);
00661 net2hostL(hash_index,action,k);
00662 net2hostL(label,action,k);
00663
00664 if(seas_f.tmb.t_lookup_ident(&c,hash_index,label)<0){
00665 LM_ERR("Failed to t_lookup_ident hash_idx=%d,label=%d\n",hash_index,label);
00666 goto error;
00667 }
00668 if(use_stats)
00669 action_stat(c);
00670 if(c->uas.status>=200){
00671 LM_ERR("ac_reply: trying to reply to a \"%.*s\" transaction"
00672 "that is already in completed state\n",REQ_LINE(c->uas.request).method.len,REQ_LINE(c->uas.request).method.s);
00673 goto error;
00674 }
00675 if (!(my_msg=parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
00676 LM_ERR("Failed to parse_ac_msg hash_idx=%d,label=%d\n",hash_index,label);
00677 goto error;
00678 }
00679 tb=(struct to_body*)my_msg->to->parsed;
00680 if(tb->tag_value.s && tb->tag_value.len){
00681 totag=tb->tag_value;
00682 }else{
00683 totag.s=NULL;
00684 totag.len=0;
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 }
00695 LM_DBG("Using totag=[%.*s]\n",totag.len,totag.s);
00696 if(my_msg->content_length)
00697 contentlength=(unsigned int)(long)my_msg->content_length->parsed;
00698 if(0>(i=recordroute_diff(c->uas.request,my_msg))){
00699 LM_DBG("Seems that request had more RecordRoutes than response...\n");
00700 goto error;
00701 }else
00702 LM_DBG("Recordroute Diff = %d\n",i);
00703
00704 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))){
00705 LM_ERR("ac_reply() filtering headers !\n");
00706 goto error;
00707 }
00708 headers[i]=0;
00709 new_header.s=headers;
00710 new_header.len=i;
00711
00712
00713
00714
00715 if(is_invite(c) && my_msg->first_line.u.reply.statuscode>=200 && my_msg->first_line.u.reply.statuscode<300)
00716 c->flags |= T_IS_LOCAL_FLAG;
00717
00718 body.len=contentlength;
00719 body.s=get_body(my_msg);
00720
00721 LM_DBG("Trying to construct a SipReply with: ReasonPhrase:[%.*s] body:[%.*s] headers:[%.*s] totag:[%.*s]\n",\
00722 my_msg->first_line.u.reply.reason.len,my_msg->first_line.u.reply.reason.s,\
00723 body.len,body.s,new_header.len,new_header.s,totag.len,totag.s);
00724
00725 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){
00726 LM_ERR("Failed to t_reply\n");
00727 goto error;
00728 }
00729 retval=0;
00730 goto exit;
00731 error:
00732 retval = -1;
00733 seas_f.tmb.unref_cell(c);
00734 exit:
00735 if(ttag)
00736 pkg_free(ttag);
00737 if(my_msg){
00738 free_sip_msg_lite(my_msg);
00739 pkg_free(my_msg);
00740 }
00741 return retval;
00742 }
00743
00744 static inline struct sip_msg *parse_ac_msg(hdr_flags_t flags,char *start,int len)
00745 {
00746 struct sip_msg *my_msg;
00747 my_msg=NULL;
00748 if(!(my_msg=pkg_malloc(sizeof(struct sip_msg)))){
00749 LM_ERR("ac_reply: out of memory!\n");
00750 goto error;
00751 }
00752 memset(my_msg,0,sizeof(struct sip_msg));
00753 my_msg->buf=start;
00754 my_msg->len=len;
00755 LM_DBG("Action Message:[%.*s]\n",len,start);
00756 if(0>parse_msg(start,len,my_msg)){
00757 LM_ERR("parse_ac_msg: parsing sip_msg");
00758 goto error;
00759 }
00760 if(0>parse_headers(my_msg,flags,0)){
00761 LM_ERR("parse_ac_msg: parsing headers\n");
00762 goto error;
00763 }
00764 return my_msg;
00765 error:
00766 if(my_msg){
00767 free_sip_msg_lite(my_msg);
00768 pkg_free(my_msg);
00769 }
00770 return NULL;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 int ac_sl_msg(as_p the_as,char *action,int len)
00782 {
00783 char processor_id;
00784 struct sip_msg *my_msg;
00785 str *uri;
00786 struct proxy_l *proxy;
00787 rr_t *my_route;
00788 int i,k,retval;
00789 unsigned int flags;
00790 enum sip_protos proto;
00791
00792 my_msg=NULL;
00793 i=k=0;
00794
00795 net2hostL(flags,action,k);
00796 processor_id=action[k++];
00797 proxy=0;
00798
00799 if(!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))){
00800 LM_ERR("out of memory!\n");
00801 goto error;
00802 }
00803 if(my_msg->first_line.type == SIP_REQUEST)
00804 LM_DBG("forwarding request:\"%.*s\" statelessly \n",my_msg->first_line.u.request.method.len+1+\
00805 my_msg->first_line.u.request.uri.len,my_msg->first_line.u.request.method.s);
00806 else
00807 LM_DBG("forwarding reply:\"%.*s\" statelessly \n",my_msg->first_line.u.reply.status.len+1+\
00808 my_msg->first_line.u.reply.reason.len,my_msg->first_line.u.reply.status.s);
00809
00810 if (my_msg->route) {
00811 if (parse_rr(my_msg->route) < 0) {
00812 LM_ERR( "Error while parsing Route body\n");
00813 goto error;
00814 }
00815 my_route = (rr_t*)my_msg->route->parsed;
00816 uri=&(my_route->nameaddr.uri);
00817 }else{
00818 uri = GET_RURI(my_msg);
00819 }
00820 my_msg->force_send_socket=grep_sock_info(&my_msg->via1->host,my_msg->via1->port,my_msg->via1->proto);
00821
00822
00823
00824
00825 proxy=uri2proxy(uri,PROTO_NONE);
00826 if (proxy==0) {
00827 LM_ERR("unable to create proxy from URI \n");
00828 goto error;
00829 }
00830 proto=proxy->proto;
00831
00832 if(0>forward_sl_request(my_msg,proxy,proto))
00833 goto error;
00834 retval=0;
00835 goto exit;
00836 error:
00837 retval = -1;
00838 exit:
00839 if(proxy){
00840 free_proxy(proxy);
00841 pkg_free(proxy);
00842 }
00843 if(my_msg){
00844 free_sip_msg_lite(my_msg);
00845 pkg_free(my_msg);
00846 }
00847 return retval;
00848 }
00849
00850 static inline void free_sip_msg_lite(struct sip_msg *my_msg)
00851 {
00852 if(my_msg){
00853
00854 if (my_msg->new_uri.s) { pkg_free(my_msg->new_uri.s); my_msg->new_uri.len=0; }
00855 if (my_msg->dst_uri.s) { pkg_free(my_msg->dst_uri.s); my_msg->dst_uri.len=0; }
00856 if (my_msg->path_vec.s) { pkg_free(my_msg->path_vec.s);my_msg->path_vec.len=0; }
00857 if (my_msg->headers) free_hdr_field_lst(my_msg->headers);
00858 if (my_msg->add_rm) free_lump_list(my_msg->add_rm);
00859 if (my_msg->body_lumps) free_lump_list(my_msg->body_lumps);
00860
00861
00862
00863
00864 }
00865 }
00866
00867 int forward_sl_request(struct sip_msg *msg,struct proxy_l *proxy,int proto)
00868 {
00869 union sockaddr_union *to;
00870 struct socket_info *send_sock;
00871 int ret;
00872
00873 to = (union sockaddr_union*)pkg_malloc(sizeof(union sockaddr_union));
00874 ret = -1;
00875
00876 hostent2su(to, &proxy->host, proxy->addr_idx,
00877 (proxy->port)?proxy->port:SIP_PORT);
00878
00879 do {
00880 send_sock=get_send_socket(msg, to, proto);
00881 if (send_sock==0){
00882 LM_ERR( "cannot forward to af %d, "
00883 "proto %d no corresponding listening socket\n",
00884 to->s.sa_family, proto);
00885 continue;
00886 }
00887 LM_DBG("Sending:\n%.*s.\n", (int)msg->len,msg->buf);
00888 if (msg_send(send_sock, proto, to, 0, msg->buf,msg->len)<0){
00889 LM_ERR("Error sending message !!\n");
00890 continue;
00891 }
00892 ret = 0;
00893 break;
00894 }while( get_next_su( proxy, to, 0)==0 );
00895
00896 pkg_free(to);
00897 return ret;
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 int ac_uac_req(as_p the_as,char *action,int len)
00913 {
00914 unsigned int flags,cseq;
00915 char err_buf[MAX_REASON_LEN],processor_id;
00916 struct sip_msg *my_msg;
00917 struct to_body *fb,*tb;
00918 struct cseq_body *cseqb;
00919 struct as_uac_param *the_param;
00920 dlg_t *my_dlg;
00921 int i,k,retval,uac_id,sip_error,ret,err_ret;
00922 long clen;
00923 str headers,body,fake_uri;
00924
00925 headers.s=body.s=fake_uri.s=NULL;
00926 my_dlg=NULL;
00927 my_msg=NULL;
00928 the_param=NULL;
00929 i=k=clen=0;
00930
00931 net2hostL(flags,action,k);
00932 net2hostL(uac_id,action,k);
00933
00934 processor_id=action[k++];
00935
00936 if(!(headers.s=pkg_malloc(MAX_HEADER))){
00937 LM_ERR("Out of Memory!!");
00938 goto error;
00939 }
00940 headers.len=0;
00941 LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id);
00942 if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
00943 LM_ERR("out of memory!\n");
00944 goto error;
00945 }
00946 if(my_msg->first_line.type==SIP_REPLY){
00947 LM_ERR("trying to create a UAC with a SIP response!!\n");
00948 goto error;
00949 }
00950 if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
00951 LM_ERR("parsing headers\n");
00952 goto error;
00953 }
00954 if(parse_from_header(my_msg)<0){
00955 LM_ERR("parsing from header ! \n");
00956 goto error;
00957 }
00958 if(check_transaction_quadruple(my_msg)==0){
00959 as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0);
00960 LM_ERR("Headers missing (to,from,call-id,cseq)?");
00961 goto error;
00962 }
00963 if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) ||
00964 !(get_from(my_msg)->tag_value.len)){
00965 as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0);
00966 LM_ERR("From tag missing");
00967 goto error;
00968 }
00969 fb=my_msg->from->parsed;
00970 tb=my_msg->to->parsed;
00971 cseqb=my_msg->cseq->parsed;
00972 if(0!=(str2int(&cseqb->number,&cseq))){
00973 LM_DBG("unable to parse CSeq\n");
00974 goto error;
00975 }
00976 if(my_msg->first_line.u.request.method_value != METHOD_ACK &&
00977 my_msg->first_line.u.request.method_value != METHOD_CANCEL) {
00978
00979 cseq--;
00980 }
00981 if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\
00982 &(fb->uri),&(tb->uri),&my_dlg) < 0) {
00983 as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0);
00984 LM_ERR("Error while creating new dialog\n");
00985 goto error;
00986 }
00987 if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) {
00988 as_action_fail_resp(uac_id,SE_UAC,
00989 "Error adding the display names to the new dialog",0);
00990 LM_ERR("failed to add display names to the new dialog\n");
00991 goto error;
00992 }
00993
00994 if(tb->tag_value.s && tb->tag_value.len)
00995 shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value);
00996
00997
00998
00999
01000
01001 server_signature=0;
01002 my_dlg->state = DLG_CONFIRMED;
01003 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))) {
01004 LM_ERR("Unable to extract allowed headers!!\n");
01005 goto error;
01006 }
01007 headers.s[headers.len]=0;
01008
01009 if(my_msg->content_length)
01010 clen=(long)get_content_length(my_msg);
01011 if(clen!=0){
01012 if(!(body.s=pkg_malloc(clen))){
01013 LM_ERR("Out of Memory!");
01014 goto error;
01015 }
01016 memcpy(body.s,get_body(my_msg),clen);
01017 body.len=clen;
01018 body.s[clen]=0;
01019 LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\
01020 body.len,body.len,body.s,headers.len,headers.len,headers.s);
01021
01022 }else{
01023 body.s=NULL;
01024 body.len=0;
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
01037 LM_ERR("out of shared memory\n");
01038 goto error;
01039 }
01040 the_param->who=my_as;
01041 the_param->uac_id=uac_id;
01042 the_param->processor_id=processor_id;
01043 the_param->destroy_cb_set=0;
01044
01045 shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri);
01046
01047 if (my_msg->route) {
01048 if (parse_rr(my_msg->route) < 0) {
01049 LM_ERR( "Error while parsing Route body\n");
01050 goto error;
01051 }
01052
01053 my_dlg->route_set=(rr_t*)my_msg->route->parsed;
01054
01055
01056
01057
01058 }
01059 calculate_hooks(my_dlg);
01060 if(flags & SPIRAL_FLAG){
01061 memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
01062 headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
01063 headers.s[headers.len]=0;
01064 fake_uri.s=pkg_malloc(200);
01065 fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);
01066
01067 if(fake_uri.len<0){
01068 LM_ERR("printing local uri\n");
01069 goto error;
01070 }
01071 my_dlg->hooks.next_hop=&fake_uri;
01072 }
01073 my_dlg->T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ;
01074 ret=seas_f.tmb.t_request_within(&(my_msg->first_line.u.request.method),&headers,&body,my_dlg,uac_cb,(void *)the_param);
01075
01076
01077 my_dlg->route_set=(rr_t *)0;
01078 if (ret <= 0) {
01079 err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
01080 LM_ERR("Error on request_within %s\n",err_buf );
01081 if(err_ret > 0) {
01082 as_action_fail_resp(uac_id,ret,err_buf,0);
01083 }else{
01084 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
01085 }
01086 goto error;
01087 }
01088 retval=0;
01089 goto exit;
01090 error:
01091 retval = -1;
01092 if(the_param)
01093 shm_free(the_param);
01094 exit:
01095 seas_f.tmb.free_dlg(my_dlg);
01096 if(headers.s)
01097 pkg_free(headers.s);
01098 if(body.s)
01099 pkg_free(body.s);
01100 if(fake_uri.s)
01101 pkg_free(fake_uri.s);
01102 if(my_msg){
01103 if(my_msg->headers)
01104 free_hdr_field_lst(my_msg->headers);
01105 pkg_free(my_msg);
01106 }
01107 return retval;
01108 }
01109
01110
01111
01112
01113 int print_local_uri(as_p as,char processor_id,char *where,int len)
01114 {
01115 int i;
01116 struct socket_info *si;
01117 str proto;
01118 proto.s=NULL;
01119 proto.len=0;
01120 for(i=0;i<MAX_BINDS;i++){
01121 if(as->bound_processor[i]==processor_id)
01122 break;
01123 }
01124 if(i==MAX_BINDS){
01125 LM_DBG("processor ID not found\n");
01126 return -1;
01127 }
01128 si=as->binds[i];
01129 switch(si->proto){
01130 case PROTO_UDP:
01131 proto.s="";
01132 proto.len=0;
01133 break;
01134 case PROTO_TCP:
01135 proto.s=TRANSPORT_PARAM "TCP";
01136 proto.len=TRANSPORT_PARAM_LEN + 3;
01137 break;
01138 case PROTO_TLS:
01139 proto.s=TRANSPORT_PARAM "TLS";
01140 proto.len=TRANSPORT_PARAM_LEN + 3;
01141 break;
01142 case PROTO_SCTP:
01143 proto.s=TRANSPORT_PARAM "SCTP";
01144 proto.len=TRANSPORT_PARAM_LEN + 4;
01145 break;
01146 }
01147 switch(si->address.af){
01148 case AF_INET:
01149 i=snprintf(where,len,"sip:%d.%d.%d.%d:%u%.*s",si->address.u.addr[0],si->address.u.addr[1],\
01150 si->address.u.addr[2],si->address.u.addr[3],si->port_no,proto.len,proto.s);
01151 break;
01152 case AF_INET6:
01153 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]),\
01154 htons(si->address.u.addr16[2]), htons(si->address.u.addr16[3]), htons(si->address.u.addr16[4]), htons(si->address.u.addr16[5]),\
01155 htons(si->address.u.addr16[6]), htons(si->address.u.addr16[7]),si->port_no,proto.len,proto.s);
01156 break;
01157 default:
01158 LM_ERR("address family unknown\n");
01159 return -1;
01160 }
01161 if(i>len){
01162 LM_ERR("Output was truncated!!\n");
01163 return -1;
01164 }else if(i<0){
01165 LM_ERR("Error on snprintf\n");
01166 return i;
01167 }
01168 return i;
01169 }
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182 void get_raw_uri(str* _s)
01183 {
01184 char* aq;
01185
01186 if (_s->s[_s->len - 1] == '>') {
01187 aq = find_not_quoted(_s, '<');
01188 _s->len -= aq - _s->s + 2;
01189 _s->s = aq + 1;
01190 }
01191 }
01192
01193
01194
01195
01196
01197
01198
01199
01200 static inline int calculate_hooks(dlg_t* _d)
01201 {
01202 str* uri;
01203 struct sip_uri puri;
01204
01205 if (_d->route_set) {
01206 uri = &_d->route_set->nameaddr.uri;
01207 if (parse_uri(uri->s, uri->len, &puri) < 0) {
01208 LM_ERR( "Error while parsing URI\n");
01209 return -1;
01210 }
01211
01212 if (puri.lr.s) {
01213 if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
01214 else _d->hooks.request_uri = &_d->rem_uri;
01215 _d->hooks.next_hop = &_d->route_set->nameaddr.uri;
01216 _d->hooks.first_route = _d->route_set;
01217 } else {
01218 _d->hooks.request_uri = &_d->route_set->nameaddr.uri;
01219 _d->hooks.next_hop = _d->hooks.request_uri;
01220 _d->hooks.first_route = _d->route_set->next;
01221 _d->hooks.last_route = &_d->rem_target;
01222 }
01223 } else {
01224 if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
01225 else _d->hooks.request_uri = &_d->rem_uri;
01226 _d->hooks.next_hop = _d->hooks.request_uri;
01227 }
01228
01229 if ((_d->hooks.request_uri) && (_d->hooks.request_uri->s) && (_d->hooks.request_uri->len)) {
01230 _d->hooks.ru.s = _d->hooks.request_uri->s;
01231 _d->hooks.ru.len = _d->hooks.request_uri->len;
01232 _d->hooks.request_uri = &_d->hooks.ru;
01233 get_raw_uri(_d->hooks.request_uri);
01234 }
01235 if ((_d->hooks.next_hop) && (_d->hooks.next_hop->s) && (_d->hooks.next_hop->len)) {
01236 _d->hooks.nh.s = _d->hooks.next_hop->s;
01237 _d->hooks.nh.len = _d->hooks.next_hop->len;
01238 _d->hooks.next_hop = &_d->hooks.nh;
01239 get_raw_uri(_d->hooks.next_hop);
01240 }
01241
01242 return 0;
01243 }
01244
01245
01246
01247
01248
01249
01250 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)
01251 {
01252 struct hdr_field *hf;
01253 rr_t *rb;
01254 struct via_body *vb;
01255 int len,k,rtcnt,i;
01256
01257 len=0;
01258 rtcnt=allow_top_Rroutes;
01259 rb=NULL;
01260 vb=NULL;
01261
01262 for(hf=my_msg->headers;hf;hf=hf->next){
01263 if(forbidden_hdrs & HDR_T2F(hf->type)){
01264 LM_DBG("Skipping header (%.*s)\n",hf->name.len,hf->name.s);
01265 continue;
01266 }else if(hf->type==HDR_VIA_T && strip_top_vias > 0){
01267
01268 for(i=0,vb=hf->parsed;vb;vb=vb->next,i++);
01269 if(i<=strip_top_vias){
01270 LM_DBG("Stripping vias [%.*s]\n",hf->len,hf->name.s);
01271
01272 strip_top_vias-=i;
01273 }else{
01274 assert(i>1);
01275 vb=hf->parsed;
01276 while(strip_top_vias--)
01277 vb=vb->next;
01278 k= (hf->name.s + hf->len) - vb->name.s;
01279 LM_DBG("Stripping vias [%.*s]\n",(int)(vb->name.s-hf->name.s),
01280 hf->name.s);
01281 if(k+VIA_LEN<headers_len){
01282 memcpy(headers+len,VIA,VIA_LEN);
01283 len+=VIA_LEN;
01284 memcpy(headers+len,vb->name.s,k);
01285 len+=k;
01286 }else{
01287 LM_ERR("Out Of Space !!\n");
01288 goto error;
01289 }
01290 }
01291 }else if(hf->type==HDR_RECORDROUTE_T && rtcnt>=0){
01292 if(rtcnt==0)
01293 continue;
01294 if(!hf->parsed && 0>parse_rr(hf)){
01295 LM_ERR("parsing Record-Route:\"%.*s\"\n",hf->body.len,hf->body.s);
01296 goto error;
01297 }
01298 for(i=0,rb=hf->parsed;rb;rb=rb->next,i++);
01299 if(i<=rtcnt){
01300 if((len+hf->len)<headers_len){
01301 LM_DBG("Allowing RecordRoute [%.*s]\n",hf->len,hf->name.s);
01302 memcpy(headers+len,hf->name.s,hf->len);
01303 len+=hf->len;
01304 }else{
01305 LM_ERR("Unable to keep recordroute (not enough space left in headers) Discarding \"%.*s\" \n",hf->name.len,hf->name.s);
01306 goto error;
01307 }
01308
01309
01310 rtcnt-=i;
01311 }else{
01312 assert(rtcnt>0);
01313 rb=hf->parsed;
01314 while(--rtcnt)
01315 rb=rb->next;
01316 k= (((rb->nameaddr.name.s) + rb->len)-hf->name.s) ;
01317 if(len+k+CRLF_LEN<headers_len){
01318 memcpy(headers+len,hf->name.s,k);
01319 LM_DBG("Allowing RecordRoute [%.*s\r\n]\n",k,hf->name.s);
01320 len+=k;
01321 memcpy(headers+len,CRLF,CRLF_LEN);
01322 len+=CRLF_LEN;
01323 }else{
01324 LM_ERR("Out Of Space !!\n");
01325 goto error;
01326 }
01327 }
01328 if(hf->parsed){
01329 free_rr((rr_t **)(void*)(&hf->parsed));
01330 hf->parsed=NULL;
01331 }
01332 }else{
01333 if((len+hf->len)<headers_len){
01334 memcpy(headers+len,hf->name.s,hf->len);
01335 len+=hf->len;
01336 }else{
01337 LM_WARN("Too many headers. Discarding \"%.*s\" \n",
01338 hf->name.len,hf->name.s);
01339 }
01340 }
01341 }
01342 return len;
01343 error:
01344 return -1;
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 int as_action_fail_resp(int uac_id,int sip_error,char *err_buf,int i)
01359 {
01360 char msg[14+MAX_REASON_LEN];
01361 int k, ev_len;
01362 k=4;
01363 if(i==0)
01364 i=strlen(err_buf);
01365 if(i>MAX_REASON_LEN){
01366 LM_ERR("Error Reason bigger than MAX_REASON_LEN\n");
01367 return -1;
01368 }
01369 msg[k++]=AC_RES_FAIL;
01370 uac_id=htonl(uac_id);
01371 memcpy(msg+k,&uac_id,4);
01372 k+=4;
01373 sip_error=htonl(sip_error);
01374 memcpy(msg+k,&sip_error,4);
01375 k+=4;
01376 msg[k++]=(char)(unsigned char)i;
01377 memcpy(msg+k,err_buf,i);
01378 k+=i;
01379 ev_len=htonl(k);
01380 memcpy(msg,&ev_len,4);
01381 write(my_as->u.as.action_fd,msg,k);
01382 return 0;
01383 }
01384
01385
01386
01387
01388
01389 void uac_cleanup_cb(struct cell* t, int type, struct tmcb_params *rcvd_params)
01390 {
01391 struct as_uac_param *ev_info;
01392
01393 ev_info=(struct as_uac_param*)*rcvd_params->param;
01394
01395 if(ev_info) {
01396 shm_free(ev_info);
01397 *rcvd_params->param=NULL;
01398 }
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 void uac_cb(struct cell* t, int type,struct tmcb_params *rcvd_params)
01413 {
01414 as_msg_p my_as_ev=0;
01415 int mylen,code,i;
01416 struct as_uac_param *ev_info;
01417 struct sip_msg *msg;
01418 char *buffer;
01419
01420 ev_info=(struct as_uac_param*)*rcvd_params->param;
01421 msg=rcvd_params->rpl;
01422 code=rcvd_params->code;
01423 buffer=0;
01424 if(!ev_info || !ev_info->who){
01425 return;
01426 }
01427
01428 if(type == TMCB_LOCAL_COMPLETED && !ev_info->destroy_cb_set) {
01429 if(seas_f.tmb.register_tmcb(NULL, t, TMCB_TRANS_DELETED, uac_cleanup_cb, (void*)ev_info, NULL) <= 0) {
01430 LM_ERR( "register_tmcb for destroy callback failed\n");
01431 goto error;
01432 }
01433 ev_info->destroy_cb_set = 1;
01434 }
01435
01436 LM_DBG("reply to UAC Transaction for AS:%.*s code: %d\n",
01437 ev_info->who->name.len,ev_info->who->name.s,code);
01438 LM_DBG("transaction %p Nr_of_outgoings:%d is_Local:%c\n",
01439 t,t->nr_of_outgoings,is_local(t)?'y':'n');
01440 for(i=0;i<t->nr_of_outgoings;i++)
01441 LM_DBG("UAC[%d].last_received=%d\n",i,t->uac[i].last_received);
01442 if(!(my_as_ev=shm_malloc(sizeof(as_msg_t)))){
01443 LM_ERR("no more shared mem\n");
01444 goto error;
01445 }
01446 if(!(buffer=create_as_action_reply(t,rcvd_params,ev_info->uac_id,ev_info->processor_id,&mylen))){
01447 LM_ERR("failed to encode message\n");
01448 goto error;
01449 }
01450 my_as_ev->as = ev_info->who;
01451 my_as_ev->msg = buffer;
01452 my_as_ev->len = mylen;
01453 my_as_ev->type = RES_IN;
01454 my_as_ev->transaction = t;
01455 if(write(write_pipe,&my_as_ev,sizeof(as_msg_p))<=0){
01456 goto error;
01457 }
01458 goto exit;
01459 error:
01460 if(my_as_ev){
01461 shm_free(my_as_ev);
01462 }
01463 if(buffer)
01464 shm_free(buffer);
01465 exit:
01466 return ;
01467 }
01468
01469 char* create_as_action_reply(struct cell *c,struct tmcb_params *params,int uac_id,char processor_id,int *evt_len)
01470 {
01471 int i;
01472 unsigned int code,flags;
01473 unsigned short int port;
01474 unsigned int k,len;
01475 char *buffer;
01476 struct sip_msg *msg;
01477 if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
01478 LM_ERR("create_as_action_reply Out Of Memory !!\n");
01479 return 0;
01480 }
01481 msg=0;
01482 *evt_len=0;
01483 flags=0;
01484 if(params->rpl==FAKED_REPLY)
01485 flags=FAKED_REPLY_FLAG;
01486
01487 k=4;
01488
01489 buffer[k++]=(unsigned char)RES_IN;
01490
01491 buffer[k++]=processor_id;
01492
01493 flags=htonl(flags);
01494 memcpy(buffer+k,&flags,4);
01495 k+=4;
01496
01497 if(!(params->rpl == FAKED_REPLY)) {
01498 msg=params->rpl;
01499
01500 buffer[k++]=(unsigned char)msg->rcv.proto;
01501
01502 len=msg->rcv.src_ip.len;
01503 buffer[k++]=(unsigned char)len;
01504 memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
01505 k+=len;
01506
01507 len=msg->rcv.dst_ip.len;
01508 buffer[k++]=(unsigned char)len;
01509 memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
01510 k+=len;
01511
01512 port=htons(msg->rcv.src_port);
01513 memcpy(buffer+k,&port,2);
01514 k+=2;
01515
01516 port=htons(msg->rcv.dst_port);
01517 memcpy(buffer+k,&port,2);
01518 k+=2;
01519 }else{
01520
01521 buffer[k++]=0;
01522
01523 buffer[k++]=0;
01524
01525 buffer[k++]=0;
01526
01527 buffer[k++]=0;
01528 buffer[k++]=0;
01529 buffer[k++]=0;
01530 buffer[k++]=0;
01531 }
01532
01533 i=htonl(c->hash_index);
01534 memcpy(buffer+k,&i,4);
01535 k+=4;
01536
01537 i=(!strncmp(c->method.s,"CANCEL",6)) ? \
01538 htonl(((struct as_uac_param*)*params->param)->label) : \
01539 htonl(c->label);
01540 memcpy(buffer+k,&i,4);
01541 k+=4;
01542
01543 uac_id=htonl(uac_id);
01544 memcpy(buffer+k,&uac_id,4);
01545 k+=4;
01546
01547 code=htonl(params->code);
01548 memcpy(buffer+k,&code,4);
01549 k+=4;
01550
01551 if(params->rpl != FAKED_REPLY) {
01552 if((i=encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k))<0){
01553 LM_ERR("failed to encode msg\n");
01554 goto error;
01555 }
01556 k+=i;
01557 }
01558 *evt_len=k;
01559 k=htonl(k);
01560 memcpy(buffer,&k,4);
01561 return buffer;
01562 error:
01563 return 0;
01564 }
01565
01566