void free_reply_lump( struct lump_rpl *lump) { struct lump_rpl *foo, *bar; for(foo=lump; foo;) { bar=foo->next; free_lump_rpl(foo); foo = bar; } }
void del_nonshm_lump_rpl( struct lump_rpl **head_list) { struct lump_rpl *foo; while( (*head_list) && (((*head_list)->flags&LUMP_RPL_SHMEM)==0) ) { foo = (*head_list); (*head_list) = foo->next; free_lump_rpl( foo ); } }
void del_nonshm_lump_rpl(struct lump_rpl** list) { struct lump_rpl* it, *tmp; struct lump_rpl** pred; it = *list; pred = list; while(it) { if (!(it->flags & LUMP_RPL_SHMEM)) { tmp = it; *pred = it->next; it = it->next; free_lump_rpl(tmp); continue; } pred = &it->next; it = it->next; } }
int t_reply_with_body( struct cell *trans, unsigned int code, str *text, str *body, str *new_header, str *to_tag ) { struct lump_rpl *hdr_lump; struct lump_rpl *body_lump; str rpl; int ret; struct bookmark bm; struct sip_msg* p_msg = trans->uas.request; str to_tag_rpl= {0, 0}; /* add the lumps for new_header and for body (by bogdan) */ if (new_header && new_header->len) { hdr_lump = add_lump_rpl( p_msg, new_header->s, new_header->len, LUMP_RPL_HDR ); if ( !hdr_lump ) { LM_ERR("failed to add hdr lump\n"); goto error; } } else { hdr_lump = 0; } /* body lump */ if(body && body->len) { body_lump = add_lump_rpl( p_msg, body->s, body->len, LUMP_RPL_BODY ); if (body_lump==0) { LM_ERR("failed add body lump\n"); goto error_1; } } else { body_lump = 0; } if(to_tag && to_tag->len) { rpl.s = build_res_buf_from_sip_req(code, text, to_tag, p_msg, (unsigned int*)&rpl.len, &bm); to_tag_rpl = *to_tag; } else if (code>=180 && p_msg->to && (get_to(p_msg)->tag_value.s==0 || get_to(p_msg)->tag_value.len==0)) { calc_crc_suffix( p_msg, tm_tag_suffix ); rpl.s = build_res_buf_from_sip_req(code,text, &tm_tag, p_msg, (unsigned int*)&rpl.len, &bm); to_tag_rpl.s = tm_tag.s; to_tag_rpl.len = TOTAG_VALUE_LEN; } else { rpl.s = build_res_buf_from_sip_req(code,text, 0 /*no to-tag*/, p_msg, (unsigned int*)&rpl.len, &bm); } /* since the msg (trans->uas.request) is a clone into shm memory, to avoid * memory leak or crashing (lumps are create in private memory) I will * remove the lumps by myself here (bogdan) */ if ( hdr_lump ) { unlink_lump_rpl( p_msg, hdr_lump); free_lump_rpl( hdr_lump ); } if( body_lump ) { unlink_lump_rpl( p_msg, body_lump); free_lump_rpl( body_lump ); } if (rpl.s==0) { LM_ERR("failed in doing build_res_buf_from_sip_req()\n"); goto error; } ret=_reply_light( trans, rpl.s, rpl.len, code, to_tag_rpl.s, to_tag_rpl.len, 1 /* lock replies */, &bm ); /* mark the transaction as replied */ if (code>=200) set_kr(REQ_RPLD); return ret; error_1: if ( hdr_lump ) { unlink_lump_rpl( p_msg, hdr_lump); free_lump_rpl( hdr_lump ); } error: return -1; }
/* UPDATED + CHECKED */ static inline char *run_redirect( struct cpl_interpreter *intr ) { struct location *loc; struct lump_rpl *lump; unsigned short attr_name; unsigned short permanent; unsigned short n; char *p; str lump_str; char *cp; int i; permanent = NO_VAL; /* sanity check */ if (NR_OF_KIDS(intr->ip)!=0) { LM_ERR("REDIRECT node doesn't suppose " "to have any sub-nodes. Found %d!\n",NR_OF_KIDS(intr->ip)); goto script_error; } /* read the attributes of the REDIRECT node*/ for( i=NR_OF_ATTR(intr->ip),p=ATTR_PTR(intr->ip) ; i>0 ; i-- ) { get_basic_attr( p, attr_name, n, intr, script_error); switch (attr_name) { case PERMANENT_ATTR: if (n!=YES_VAL && n!=NO_VAL) { LM_ERR("unsupported value (%d)" " in attribute PERMANENT for REDIRECT node",n); goto script_error; } permanent = n; break; default: LM_ERR("unknown attribute " "(%d) in REDIRECT node\n",attr_name); goto script_error; } } /* build the lump for Contact header */ lump_str.len = 9 /*"Contact: "*/; for(loc=intr->loc_set;loc;loc=loc->next) lump_str.len += 1/*"<"*/ + loc->addr.uri.len + 7/*">;q=x.x"*/ + 2*(loc->next!=0)/*" ,"*/; lump_str.len += CRLF_LEN; lump_str.s = pkg_malloc( lump_str.len ); if(!lump_str.s) { LM_ERR("out of pkg memory!\n"); goto runtime_error; } cp = lump_str.s; memcpy( cp , "Contact: " , 9); cp += 9; for(loc=intr->loc_set;loc;loc=loc->next) { *(cp++) = '<'; memcpy(cp,loc->addr.uri.s,loc->addr.uri.len); cp += loc->addr.uri.len; memcpy(cp,">;q=",4); cp += 4; *(cp++) = (loc->addr.priority!=10)?'0':'1'; *(cp++) = '.'; *(cp++) = '0'+(loc->addr.priority%10); if (loc->next) { *(cp++) = ' '; *(cp++) = ','; } } memcpy(cp,CRLF,CRLF_LEN); /* if still stateless and FORCE_STATEFUL set -> build the transaction */ if ( !(intr->flags&CPL_IS_STATEFUL) && intr->flags&CPL_FORCE_STATEFUL) { i = cpl_fct.tmb.t_newtran( intr->msg ); if (i<0) { LM_ERR("failed to build new transaction!\n"); pkg_free( lump_str.s ); goto runtime_error; } else if (i==0) { LM_ERR("processed INVITE is a retransmission!\n"); /* instead of generating an error is better just to break the * script by returning EO_SCRIPT */ pkg_free( lump_str.s ); return EO_SCRIPT; } intr->flags |= CPL_IS_STATEFUL; } /* add the lump to the reply */ lump = add_lump_rpl( intr->msg, lump_str.s , lump_str.len , LUMP_RPL_HDR); if(!lump) { LM_ERR("unable to add lump_rpl! \n"); pkg_free( lump_str.s ); goto runtime_error; } /* send the reply */ if (permanent) i = cpl_fct.slb.freply( intr->msg,301,&cpl_301_reason); else i = cpl_fct.slb.freply( intr->msg,302,&cpl_302_reason); /* msg which I'm working on can be in private memory or is a clone into * shared memory (if I'm after a failed proxy); So, it's better to removed * by myself the lump that I added previously */ unlink_lump_rpl( intr->msg, lump); free_lump_rpl( lump ); if (i!=1) { LM_ERR("unable to send redirect reply!\n"); goto runtime_error; } return EO_SCRIPT; runtime_error: return CPL_RUNTIME_ERROR; script_error: return CPL_SCRIPT_ERROR; }