Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/* 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;
}