Esempio n. 1
0
/*
 * Matches from uri against patterns returned from database.  Returns number
 * of matches or -1 if none of the patterns match.
 */
static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r)
{
	int i, tag_avp_type;
	str uri;
	char uri_string[MAX_URI_SIZE+1];
	db_row_t* row;
	db_val_t* val;
	regex_t preg;
	int_str tag_avp, avp_val;
	int count = 0;

	if (IS_SIP(msg)) {
		if (parse_from_header(msg) < 0) return -1;
		uri = get_from(msg)->uri;
		if (uri.len > MAX_URI_SIZE) {
			LM_ERR("message has From URI too large\n");
			return -1;
		}
		memcpy(uri_string, uri.s, uri.len);
		uri_string[uri.len] = (char)0;
	}
	get_tag_avp(&tag_avp, &tag_avp_type);

	row = RES_ROWS(_r);

	for(i = 0; i < RES_ROW_N(_r); i++) {
		val = ROW_VALUES(row + i);
		if ((ROW_N(row + i) == 3) &&
		    (VAL_TYPE(val) == DB1_STRING) && !VAL_NULL(val) &&
		    match_proto(VAL_STRING(val), proto) &&
		    (VAL_NULL(val + 1) ||
		      ((VAL_TYPE(val + 1) == DB1_STRING) && !VAL_NULL(val + 1))) &&
		    (VAL_NULL(val + 2) ||
		      ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))))
		{
			if (!VAL_NULL(val + 1) && IS_SIP(msg)) {
				if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) {
					LM_ERR("invalid regular expression\n");
					continue;
				}
				if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
					regfree(&preg);
					continue;
				}
			    regfree(&preg);
			}
			/* Found a match */
			if (tag_avp.n && !VAL_NULL(val + 2)) {
				avp_val.s.s = (char *)VAL_STRING(val + 2);
				avp_val.s.len = strlen(avp_val.s.s);
				if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, avp_val) != 0) {
					LM_ERR("failed to set of tag_avp failed\n");
					return -1;
				}
			}
			if (!peer_tag_mode) 
				return 1;
			count++;
		}
	}
	if (!count)
		return -1;
	else 
		return count;
}
Esempio n. 2
0
/*! \brief
 * Insert manually created Record-Route header, no checks, no restrictions,
 * always adds lr parameter, only fromtag is added automatically when requested
 */
int record_route_preset(struct sip_msg* _m, str* _data)
{
	str user;
	struct to_body* from;
	struct lump* l, *lp, *ap;
	struct lump* l2;
	char *hdr, *suffix, *p, *term;
	int hdr_len, suffix_len;

	from = 0;
	user.len = 0;
	user.s = 0;

	if (add_username) {
		if (get_username(_m, &user) < 0) {
			LM_ERR("failed to extract username\n");
			return -1;
		}
	}

	if (append_fromtag) {
		if (parse_from_header(_m) < 0) {
			LM_ERR("From parsing failed\n");
			return -2;
		}
		from = (struct to_body*)_m->from->parsed;
	}

	hdr_len = RR_PREFIX_LEN;
	if (user.len)
		hdr_len += user.len + 1; /* @ */
	hdr_len += _data->len;

	suffix_len = 0;
	if (append_fromtag && from->tag_value.len) {
		suffix_len += RR_FROMTAG_LEN + from->tag_value.len;
	}

	suffix_len += RR_LR_LEN;

	hdr = pkg_malloc(hdr_len);
	term = pkg_malloc(RR_TERM_LEN);
	suffix = pkg_malloc(suffix_len);
	if (!hdr || !term || !suffix) {
		LM_ERR("no pkg memory left\n");
		return -4;
	}

	/* header */
	p = hdr;
	memcpy(p, RR_PREFIX, RR_PREFIX_LEN);
	p += RR_PREFIX_LEN;

	if (user.len) {
		memcpy(p, user.s, user.len);
		p += user.len;
		*p = '@';
		p++;
	}

	memcpy(p, _data->s, _data->len);
	p += _data->len;

	/*suffix*/
	p = suffix;
	if (append_fromtag && from->tag_value.len) {
		memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
		p += RR_FROMTAG_LEN;
		memcpy(p, from->tag_value.s, from->tag_value.len);
		p += from->tag_value.len;
	}

	memcpy(p, RR_LR, RR_LR_LEN);
	p += RR_LR_LEN;

	memcpy(term, RR_TERM, RR_TERM_LEN);

	l = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	if (!l || !l2) {
		LM_ERR("failed to create lump anchor\n");
		goto error;
	}

	if (!(l=insert_new_lump_after(l, hdr, hdr_len, 0))) {
		LM_ERR("failed to insert new lump\n");
		goto error;
	}
	hdr = NULL;

	l2 = insert_new_lump_before(l2, suffix, suffix_len, HDR_RECORDROUTE_T);
	if (l2==NULL) {
		LM_ERR("failed to insert suffix lump\n");
		goto error;
	}
	suffix = NULL;

	/* look for pending RR params */
	for( lp=NULL,ap=_m->add_rm ; ap ; ap=ap->next ) {
		if (ap->type==HDR_RECORDROUTE_T && ap->op==LUMP_NOP
		&& ap->before && ap->before->op==LUMP_ADD_OPT
		&& ap->before->u.cond==COND_FALSE) {
			/* found our phony anchor lump */
			/* jump over the anchor and conditional lumps */
			lp = ap->before->before;
			/* unlink it */
			ap->before->before = NULL;
			ap->type = 0;
			/* link the pending buffered params and go at the end of the list*/
			for ( l2->before = lp ; l2 && l2->before ; l2=l2->before);
			break;
		}
	}

	if (!(l2=insert_new_lump_before(l2, term, RR_TERM_LEN, 0))) {
		LM_ERR("failed to insert term lump");
		goto error;
	}
	term = NULL;

	return 1;
error:
	if (hdr) pkg_free(hdr);
	if (term) pkg_free(term);
	if (suffix) pkg_free(suffix);
	return -1;
}
Esempio n. 3
0
/*
 * function that simply prints the parameters passed
 */
static int siprec_start_rec(struct sip_msg *msg, str *srs, str *group,
		str *_cA, str *_cB, str *rtp, str *m_ip)
{
	int ret;
	str *aor, *display, *xml_val;
	struct src_sess *ss;
	struct dlg_cell *dlg;

	/* create the dialog, if does not exist yet */
	dlg = srec_dlg.get_dlg();
	if (!dlg) {
		if (srec_dlg.create_dlg(msg, 0) < 0) {
			LM_ERR("cannot create dialog!\n");
			return -2;
		}
		dlg = srec_dlg.get_dlg();
	}

	/* XXX: if there is a forced send socket in the message, use it
	 * this is the only way to provide a different socket for SRS, but
	 * we might need to take a different approach */
	/* check if the current dialog has a siprec session ongoing */
	if (!(ss = src_new_session(srs, rtp, m_ip, group, msg->force_send_socket))) {
		LM_ERR("cannot create siprec session!\n");
		return -2;
	}

	/* we ref the dialog to make sure it does not dissapear until we receive
	 * the reply from the SRS */
	srec_dlg.ref_dlg(dlg, 1);
	ss->dlg = dlg;

	ret = -2;

	/* caller info */
	if (_cA) {
		xml_val = _cA;
		display = aor = NULL;
	} else {
		if (parse_from_header(msg) < 0) {
			LM_ERR("cannot parse from header!\n");
			goto session_cleanup;
		}
		aor = &get_from(msg)->uri;
		display = (get_from(msg)->display.s ? &get_from(msg)->display : NULL);
		xml_val = NULL;
	}

	if (src_add_participant(ss, aor, display, xml_val, NULL) < 0) {
		LM_ERR("cannot add caller participant!\n");
		goto session_cleanup;
	}
	if (srs_fill_sdp_stream(msg, ss, &ss->participants[0], 0) < 0) {
		LM_ERR("cannot add SDP for caller!\n");
		goto session_cleanup;
	}
	/* caller info */
	if (_cB) {
		xml_val = _cB;
	} else {
		if ((!msg->to && parse_headers(msg, HDR_TO_F, 0) < 0) || !msg->to) {
			LM_ERR("inexisting or invalid to header!\n");
			goto session_cleanup;
		}
		aor = &get_to(msg)->uri;
		display = (get_to(msg)->display.s ? &get_to(msg)->display : NULL);
		xml_val = NULL;
	}

	if (src_add_participant(ss, aor, display, xml_val, NULL) < 0) {
		LM_ERR("cannot add callee pariticipant!\n");
		goto session_cleanup;
	}

	SIPREC_REF_UNSAFE(ss);
	if (srec_tm.register_tmcb(msg, 0, TMCB_RESPONSE_OUT, tm_start_recording,
			ss, src_unref_session) <= 0) {
		LM_ERR("cannot register tm callbacks\n");
		SIPREC_UNREF_UNSAFE(ss);
		goto session_cleanup;
	}
	return 1;

session_cleanup:
	src_free_session(ss);
	return ret;
}
Esempio n. 4
0
void dlg_bridge_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
{
	struct sip_msg *msg = NULL;
	dlg_transfer_ctx_t *dtc = NULL;
	struct dlg_cell *dlg = NULL;
	str s;
	str cseq;
	str empty = {"", 0};

	if(ps->param==NULL || *ps->param==0)
	{
		LM_DBG("message id not received\n");
		return;
	}
	dtc = *((dlg_transfer_ctx_t**)ps->param);
	if(dtc==NULL)
		return;
	LM_DBG("completed with status %d\n", ps->code);
	if(ps->code>=300)
		goto error;

	/* 2xx - build dialog/send refer */
	msg = ps->rpl;
	if((msg->cseq==NULL || parse_headers(msg,HDR_CSEQ_F,0)<0)
			|| msg->cseq==NULL || msg->cseq->parsed==NULL)
	{
			LM_ERR("bad sip message or missing CSeq hdr :-/\n");
			goto error;
	}
	cseq = (get_cseq(msg))->number;

	if((msg->to==NULL && parse_headers(msg, HDR_TO_F,0)<0) || msg->to==NULL)
	{
		LM_ERR("bad request or missing TO hdr\n");
		goto error;
	}
	if(parse_from_header(msg))
	{
		LM_ERR("bad request or missing FROM hdr\n");
		goto error;
	}
	if((msg->callid==NULL && parse_headers(msg,HDR_CALLID_F,0)<0)
			|| msg->callid==NULL){
		LM_ERR("bad request or missing CALLID hdr\n");
		goto error;
	}
	s = msg->callid->body;
	trim(&s);

	/* some sanity checks */
	if (s.len==0 || get_from(msg)->tag_value.len==0) {
		LM_ERR("invalid request -> callid (%d) or from TAG (%d) empty\n",
			s.len, get_from(msg)->tag_value.len);
		goto error;
	}

	dlg = build_new_dlg(&s /*callid*/, &(get_from(msg)->uri) /*from uri*/,
		&(get_to(msg)->uri) /*to uri*/,
		&(get_from(msg)->tag_value)/*from_tag*/,
		&(get_to(msg)->uri) /*use to as r-uri*/ );
	if (dlg==0) {
		LM_ERR("failed to create new dialog\n");
		goto error;
	}
	dtc->dlg = dlg;
	if (dlg_set_leg_info(dlg, &(get_from(msg)->tag_value),
				&empty, &dlg_bridge_controller, &cseq, DLG_CALLER_LEG)!=0) {
		LM_ERR("dlg_set_leg_info failed\n");
		goto error;
	}

	if (populate_leg_info(dlg, msg, t, DLG_CALLEE_LEG,
			&(get_to(msg)->tag_value)) !=0)
	{
		LM_ERR("could not add further info to the dialog\n");
		shm_free(dlg);
		goto error;
	}

	if(dlg_refer_callee(dtc)!=0)
		goto error;
	return;

error:
	dlg_transfer_ctx_free(dtc);
	return;
}
Esempio n. 5
0
int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
{
	struct to_body *pto, TO = {0}, *pfrom = NULL;
	str body= {0, 0};
	ua_pres_t dialog;
	str* res_id= NULL;
	db_key_t query_cols[8];
	db_val_t query_vals[8];
	int n_query_cols= 0;
	str auth_state= {0, 0};
	int found= 0;
	str reason = {0, 0};
	int auth_flag;
	struct hdr_field* hdr= NULL;
	int expires= -1;
	str content_type= {0, 0};
	int reply_code = 500;
	str reply_str = pu_500_rpl;

	LM_DBG("start\n");
	/* extract the dialog information and check if an existing dialog*/	
	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
				pto->uri.len, pto->uri.s );	
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0) 
		{
			LM_ERR(" 'To' header NOT parsed\n");
			reply_code = 400;
			reply_str = pu_400_rpl;
			goto error;
		}
		pto = &TO;
	}
	memset(&dialog, 0, sizeof(ua_pres_t));
	dialog.watcher_uri= &pto->uri;
	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.from_tag= pto->tag_value;
	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG("'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 ) 
		{
			LM_ERR("cannot parse From header\n");
			reply_code = 400;
			reply_str = pu_400_rpl;
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= RLS_SUBSCRIBE;

	dialog.event= get_event_flag(&msg->event->body);
	if(dialog.event< 0)
	{
		LM_ERR("unrecognized event package\n");
		reply_code = 489;
		reply_str = pu_489_rpl;
		goto error;
	}

	/* extract the subscription state */
	hdr = msg->headers;
	while (hdr!= NULL)
	{
		if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)  
		{
			found = 1;
			break;
		}
		hdr = hdr->next;
	}
	if(found==0 )
	{
		LM_ERR("'Subscription-State' header not found\n");
		goto error;
	}
	auth_state = hdr->body;

	/* extract state and reason */
	auth_flag= parse_subs_state(auth_state, &reason, &expires);
	if(auth_flag< 0)
	{
		LM_ERR("while parsing 'Subscription-State' header\n");
		goto error;
	}
	if(pua_get_record_id(&dialog, &res_id)< 0) /* verify if within a stored dialog */
	{
		LM_ERR("occured when trying to get record id\n");
		goto error;
	}
	if(res_id==0)
	{
		LM_DBG("presence dialog record not found\n");
		/* if it is a NOTIFY for a terminated SUBSCRIBE dialog in RLS, then
		 * the module might not have the dialog structure anymore
		 * - just send 200ok, it is harmless
		 */
		if(auth_flag==TERMINATED_STATE)
			goto done;
		LM_INFO("no presence dialog record for non-TERMINATED state uri pres_uri = %.*s watcher_uri = %.*s\n",
                dialog.pres_uri->len, dialog.pres_uri->s, dialog.watcher_uri->len, dialog.watcher_uri->s);
		reply_code = 481;
		reply_str = pu_481_rpl;
		goto error;
	}
		
	if(msg->content_type== NULL || msg->content_type->body.s== NULL)
	{
		LM_DBG("cannot find content type header header\n");
	}
	else
		content_type= msg->content_type->body;
					
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{	
		goto done;
	}	
	else
	{
		if(content_type.s== 0)
		{
			LM_ERR("content length != 0 and no content type header found\n");
			goto error;
		}
		body.s=get_body(msg);
		if (body.s== NULL) 
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		body.len = get_content_length( msg );

	}
	/* update in rlpres_table where rlsusb_did= res_id and resource_uri= from_uri*/

	LM_DBG("body= %.*s\n", body.len, body.s);

	query_cols[n_query_cols]= &str_rlsubs_did_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *res_id; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_resource_uri_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *dialog.pres_uri; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_updated_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	if (dbmode == RLS_DB_ONLY)
		query_vals[n_query_cols].val.int_val=
			core_hash(res_id, NULL, 0) %
				(waitn_time * rls_notifier_poll_rate
					* rls_notifier_processes);
	else
		query_vals[n_query_cols].val.int_val = UPDATED_TYPE;
	n_query_cols++;
		
	query_cols[n_query_cols]= &str_auth_state_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= auth_flag; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_reason_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	if(reason.len > 0)
	{
		query_vals[n_query_cols].val.str_val.s= reason.s;
		query_vals[n_query_cols].val.str_val.len= reason.len;
	}	
	else
	{
		query_vals[n_query_cols].val.str_val.s = "";
		query_vals[n_query_cols].val.str_val.len = 0;
	}
	n_query_cols++;

	query_cols[n_query_cols]= &str_content_type_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= content_type;
	n_query_cols++;
			
	query_cols[n_query_cols]= &str_presence_state_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= body;
	n_query_cols++;
		
	query_cols[n_query_cols]= &str_expires_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= expires+ (int)time(NULL);
	n_query_cols++;

	if (rlpres_dbf.use_table(rlpres_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto error;
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.start_transaction)
	{
		if (rlpres_dbf.start_transaction(rlpres_db) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	if (rlpres_dbf.replace != NULL)
	{
		if(rlpres_dbf.replace(rlpres_db, query_cols, query_vals, n_query_cols,
					2, 0)< 0)
		{
			LM_ERR("in sql replace\n");
			goto error;
		}
		LM_DBG("Inserted/replace in database table new record\n");
	}
	else
	{
		if(rlpres_dbf.update(rlpres_db, query_cols, 0, query_vals, query_cols+2,
						query_vals+2, 2, n_query_cols-2)< 0)
		{
			LM_ERR("in sql update\n");
			goto error;
		}

		if (rlpres_dbf.affected_rows(rlpres_db) == 0)
		{
			if(rlpres_dbf.insert(rlpres_db, query_cols, query_vals, n_query_cols)< 0)
			{
				LM_ERR("in sql insert\n");
				goto error;
			}
			LM_DBG("Inserted in database table new record\n");
		}
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.end_transaction)
	{
		if (rlpres_dbf.end_transaction(rlpres_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	LM_DBG("Updated rlpres_table\n");	
	/* reply 200OK */
done:
	if(slb.freply(msg, 200, &su_200_rpl) < 0)
	{
		LM_ERR("while sending reply\n");
		goto error;
	}

	if(res_id!=NULL)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	if (reason.s) pkg_free(reason.s);

	free_to_params(&TO);
	return 1;

error:
	if(slb.freply(msg, reply_code, &reply_str) < 0)
	{
		LM_ERR("failed sending reply\n");
	}
	if(res_id!=NULL)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	if (reason.s) pkg_free(reason.s);

	free_to_params(&TO);

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.abort_transaction)
	{
		if (rlpres_dbf.abort_transaction(rlpres_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

	return -1;
}
Esempio n. 6
0
/**
 * manage SIP message
 */
int xjab_manage_sipmsg(struct sip_msg *msg, int type)
{
	str body, dst, from_uri;
	xj_sipmsg jsmsg;
	int pipe, fl;
	t_xj_jkey jkey, *p;
	int mime;

	body.len = 0;
	body.s = 0;

	// extract message body - after that whole SIP MESSAGE is parsed
	if (type==XJ_SEND_MESSAGE)
	{
		/* get the message's body */
		body.s = get_body( msg );
		if(body.s==0) 
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		
		/* content-length (if present) must be already parsed */
		if(!msg->content_length)
		{
			LM_ERR("no Content-Length header found!\n");
			goto error;
		}
		body.len = get_content_length(msg);

		/* parse the content-type header */
		if((mime=parse_content_type_hdr(msg))<1)
		{
			LM_ERR("cannot parse Content-Type header\n");
			goto error;
		}

		/* check the content-type value */
		if(mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
			&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM)
		{
			LM_ERR("invalid content-type for"
				" a message request! type found=%d\n", mime);
			goto error;
		}
	}
	
	// check for TO and FROM headers - if is not SIP MESSAGE 
	if(parse_headers(msg,HDR_TO_F|HDR_FROM_F,0)==-1 || !msg->to || !msg->from)
	{
		LM_ERR("cannot find TO or FROM HEADERS!\n");
		goto error;
	}
	
	/* parsing from header */
	if ( parse_from_header( msg )<0 || msg->from->parsed==NULL) 
	{
		LM_DBG("cannot get FROM header\n");
		goto error;
	}
	from_uri.s = ((struct to_body*)msg->from->parsed)->uri.s;
	from_uri.len = ((struct to_body*)msg->from->parsed)->uri.len;
	if(xj_extract_aor(&from_uri, 0))
	{
		LM_DBG("cannot get AoR from FROM header\n");
		goto error;
	}

	jkey.hash = xj_get_hash(&from_uri, NULL);
	jkey.id = &from_uri;
	// get the communication pipe with the worker
	switch(type)
	{
		case XJ_SEND_MESSAGE:
		case XJ_JOIN_JCONF:
		case XJ_GO_ONLINE:
			if((pipe = xj_wlist_get(jwl, &jkey, &p)) < 0)
			{
				LM_DBG("cannot find pipe of the worker!\n");
				goto error;
			}
		break;
		case XJ_EXIT_JCONF:
		case XJ_GO_OFFLINE:
			if((pipe = xj_wlist_check(jwl, &jkey, &p)) < 0)
			{
				LM_DBG("no open Jabber session for"
						" <%.*s>!\n", from_uri.len, from_uri.s);
				goto error;
			}
		break;
		default:
			LM_DBG("ERROR:strange SIP msg type!\n");
			goto error;
	}

	// if is for going ONLINE/OFFLINE we do not need the destination
	if(type==XJ_GO_ONLINE || type==XJ_GO_OFFLINE)
		goto prepare_job;
	
	// determination of destination
	// - try to get it from new_uri, r-uri or to hdr, but check it against
	// jdomain and aliases
	dst.len = 0;
	if( msg->new_uri.len > 0)
	{
		dst.s = msg->new_uri.s;
		dst.len = msg->new_uri.len;
		if(xj_wlist_check_aliases(jwl, &dst))
			dst.len = 0;
#ifdef XJ_EXTRA_DEBUG
		else
			LM_DBG("using NEW URI for destination\n");
#endif
	}
	
	if (dst.len == 0 &&  msg->first_line.u.request.uri.s != NULL
			&& msg->first_line.u.request.uri.len > 0 )
	{
		dst.s = msg->first_line.u.request.uri.s;
		dst.len = msg->first_line.u.request.uri.len;
		if(xj_wlist_check_aliases(jwl, &dst))
			dst.len = 0;
#ifdef XJ_EXTRA_DEBUG
		else
			LM_DBG("using R-URI for destination\n");
#endif
	}

	if(dst.len == 0 && msg->to->parsed)
	{
		dst.s = ((struct to_body*)msg->to->parsed)->uri.s;
		dst.len = ((struct to_body*)msg->to->parsed)->uri.len;
		if(dst.s == NULL || xj_wlist_check_aliases(jwl, &dst))
			dst.len = 0;
#ifdef XJ_EXTRA_DEBUG
		else
			LM_DBG("using TO-URI for destination\n");
#endif
	}
	
	if(dst.len == 0)
	{
		LM_DBG("destination not found in SIP message\n");
		goto error;
	}
	
	/** skip 'sip:' and parameters in destination address */
	if(xj_extract_aor(&dst, 1))
	{
		LM_ERR("cannot get AoR for destination\n");
		goto error;
	}
#ifdef XJ_EXTRA_DEBUG
	LM_DBG("destination after correction [%.*s].\n", dst.len, dst.s);
#endif
	
prepare_job:
	//putting the SIP message parts in share memory to be accessible by workers
    jsmsg = (xj_sipmsg)shm_malloc(sizeof(t_xj_sipmsg));
	memset(jsmsg, 0, sizeof(t_xj_sipmsg));
    if(jsmsg == NULL)
    	return -1;
	
	switch(type)
	{
		case XJ_SEND_MESSAGE:
			jsmsg->msg.len = body.len;
			if((jsmsg->msg.s = (char*)shm_malloc(jsmsg->msg.len+1)) == NULL)
			{
				shm_free(jsmsg);
				goto error;
			}
			strncpy(jsmsg->msg.s, body.s, jsmsg->msg.len);
		break;
		case XJ_GO_ONLINE:
		case XJ_GO_OFFLINE:
			dst.len = 0;
			dst.s = 0;
		case XJ_JOIN_JCONF:
		case XJ_EXIT_JCONF:
			jsmsg->msg.len = 0;
			jsmsg->msg.s = NULL;
		break;
		default:
			LM_DBG("this SHOULD NOT appear\n");
			shm_free(jsmsg);
			goto error;
	}
	if(dst.len>0)
	{
		jsmsg->to.len = dst.len;
		if((jsmsg->to.s = (char*)shm_malloc(jsmsg->to.len+1))==NULL)
		{
			if(type == XJ_SEND_MESSAGE)
				shm_free(jsmsg->msg.s);
			shm_free(jsmsg);
			goto error;
		}
		strncpy(jsmsg->to.s, dst.s, jsmsg->to.len);
	}
	else
	{
		jsmsg->to.len = 0;
		jsmsg->to.s   = 0;
	}

	jsmsg->jkey = p;
	jsmsg->type = type;
	//jsmsg->jkey->hash = jkey.hash;

	LM_DBG("sending <%p> to worker through <%d>\n",	jsmsg, pipe);
	// sending the SHM pointer of SIP message to the worker
	fl = write(pipe, &jsmsg, sizeof(jsmsg));
	if(fl != sizeof(jsmsg))
	{
		LM_ERR("failed to write to worker pipe!\n");
		if(type == XJ_SEND_MESSAGE)
			shm_free(jsmsg->msg.s);
		shm_free(jsmsg->to.s);
		shm_free(jsmsg);
		goto error;
	}
	
	return 1;
error:
	return -1;
}
Esempio n. 7
0
/*
 * determines the permission to an uri
 * return values:
 * -1:	deny
 * 1:	allow
 */
static int allow_uri(struct sip_msg* msg, char* _idx, char* _sp)
{
	struct hdr_field *from;
	int idx, len;
	static char from_str[EXPRESSION_LENGTH+1];
	static char uri_str[EXPRESSION_LENGTH+1];
	pv_spec_t *sp;
	pv_value_t pv_val;

	idx = (int)(long)_idx;
	sp = (pv_spec_t *)_sp;

	/* turn off control, allow any uri */
	if ((!allow[idx].rules) && (!deny[idx].rules)) {
		LM_DBG("no rules => allow any uri\n");
		return 1;
	}

	/* looking for FROM HF */
	if ((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) {
		LM_ERR("failed to parse message\n");
		return -1;
	}

	if (!msg->from) {
		LM_ERR("FROM header field not found\n");
		return -1;
	}

	/* we must call parse_from_header explicitly */
	if ((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) {
		LM_ERR("failed to parse From body\n");
		return -1;
	}

	from = msg->from;
	len = ((struct to_body*)from->parsed)->uri.len;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("From header field is too long: %d chars\n", len);
		return -1;
	}
	strncpy(from_str, ((struct to_body*)from->parsed)->uri.s, len);
	from_str[len] = '\0';

	if (sp && (pv_get_spec_value(msg, sp, &pv_val) == 0)) {
		if (pv_val.flags & PV_VAL_STR) {
			if (pv_val.rs.len > EXPRESSION_LENGTH) {
				LM_ERR("pseudo variable value is too "
						"long: %d chars\n", pv_val.rs.len);
				return -1;
			}
			strncpy(uri_str, pv_val.rs.s, pv_val.rs.len);
			uri_str[pv_val.rs.len] = '\0';
		} else {
			LM_ERR("pseudo variable value is not string\n");
			return -1;
		}
	} else {
		LM_ERR("cannot get pseudo variable value\n");
		return -1;
	}

	LM_DBG("looking for From: %s URI: %s\n", from_str, uri_str);
	/* rule exists in allow file */
	if (search_rule(allow[idx].rules, from_str, uri_str)) {
		LM_DBG("allow rule found => URI is allowed\n");
		return 1;
	}

	/* rule exists in deny file */
	if (search_rule(deny[idx].rules, from_str, uri_str)) {
		LM_DBG("deny rule found => URI is denied\n");
		return -1;
	}

	LM_DBG("neither allow nor deny rule found => URI is allowed\n");

	return 1;
}
Esempio n. 8
0
static int sip_trace(struct sip_msg *msg, char *s1, char *s2)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+6];
	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+6];
	int_str        avp_value;
	struct usr_avp *avp;
	
	if(msg==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return -1;
	}

	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) && (trace_on_flag==NULL || *trace_on_flag==0))
	{
		LM_DBG("trace off...\n");
		return -1;
	}
	
	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}
	
	if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL
			|| msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse call-id\n");
		goto error;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	db_vals[0].val.blob_val.s = msg->buf;
	db_vals[0].val.blob_val.len = msg->len;
	
	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	if(msg->first_line.type==SIP_REQUEST)
	{
		db_vals[2].val.str_val.s = msg->first_line.u.request.method.s;
		db_vals[2].val.str_val.len = msg->first_line.u.request.method.len;
	} else {
		db_vals[2].val.str_val.s = "";
		db_vals[2].val.str_val.len = 0;
	}
		
	db_keys[3] = status_column;
	db_vals[3].type = DB_STR;
	db_vals[3].nul = 0;
	if(msg->first_line.type==SIP_REPLY)
	{
		db_vals[3].val.str_val.s = msg->first_line.u.reply.status.s;
		db_vals[3].val.str_val.len = msg->first_line.u.reply.status.len;
	} else {
		db_vals[3].val.str_val.s = "";
		db_vals[3].val.str_val.len = 0;
	}
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	siptrace_copy_proto(msg->rcv.proto, fromip_buff);
	strcat(fromip_buff, ip_addr2a(&msg->rcv.src_ip));
	strcat(fromip_buff,":");
	strcat(fromip_buff, int2str(msg->rcv.src_port, NULL));
	db_vals[4].val.string_val = fromip_buff;
	
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	// db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);;
	siptrace_copy_proto(msg->rcv.proto, toip_buff);
	strcat(toip_buff, ip_addr2a(&msg->rcv.dst_ip));
	strcat(toip_buff,":");
	strcat(toip_buff, int2str(msg->rcv.dst_port, NULL));
	db_vals[5].val.string_val = toip_buff;
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "in";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());
	
	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if(trace_on_flag!=NULL && *trace_on_flag!=0) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		if(msg->first_line.type==SIP_REPLY)
		{
			update_stat(siptrace_rpl, 1);
		} else {
			update_stat(siptrace_req, 1);
		}
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}

done:
	return 1;
error:
	return -1;
}
Esempio n. 9
0
static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps)
{
	struct sip_msg* msg;
	int_str        avp_value;
	struct usr_avp *avp;

	if(t==NULL || ps==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return;
	}
	
	msg = ps->req;
	if(msg==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) && trace_is_off(msg))
	{
		LM_DBG("trace off...\n");
		return;
	}
	
	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		return;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	if (msg->REQ_METHOD==METHOD_INVITE)
	{
		LM_DBG("noisy_timer set for tracing\n");
		t->flags |= T_NOISY_CTIMER_FLAG;
	}
	if(tmb.register_tmcb( 0, t, TMCB_REQUEST_BUILT, trace_onreq_out, 0) <=0)
	{
		LM_ERR("can't register trace_onreq_out\n");
		return;
	}

	if(tmb.register_tmcb( 0, t, TMCB_RESPONSE_IN, trace_onreply_in, 0) <=0)
	{
		LM_ERR("can't register trace_onreply_in\n");
		return;
	}

	if(tmb.register_tmcb( 0, t, TMCB_RESPONSE_OUT, trace_onreply_out, 0) <=0)
	{
		LM_ERR("can't register trace_onreply_out\n");
		return;
	}
}
Esempio n. 10
0
/* look for subscriber cell using callid and to_tag of Notify*/
struct sm_subscriber* get_subs_cell(struct sip_msg *msg, str callid_event) {
	str callid;
	str method;
	struct to_body *pto= NULL, *pfrom = NULL;
	struct sm_subscriber* s;
	unsigned int hash_code;

	method.s = msg->first_line.u.request.method.s;
	method.len = msg->first_line.u.request.method.len;

	if ( parse_headers(msg,HDR_EOH_F, 0) == -1 ){
		LM_ERR("error in parsing headers\n");
		return NULL;
	}

	// get callid from Notify
	if( msg->callid==NULL || msg->callid->body.s==NULL){
		LM_ERR("reply without callid header\n");
		return NULL;
	}
	callid = msg->callid->body;
	LM_DBG("CALLID: %.*s \n ", callid.len, callid.s );

	if (msg->from->parsed == NULL){
		if ( parse_from_header( msg )<0 ){
			LM_ERR("reply without From header\n");
			return NULL;
		}
	}

	//get From header from Notify
	pfrom = get_from(msg);
	LM_DBG("PFROM: %.*s \n ", pfrom->uri.len, pfrom->uri.s );

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0){
		LM_ERR("reply without tag value \n");
		return NULL;
	}
	if( msg->to==NULL || msg->to->body.s==NULL){
		LM_ERR("error in parse TO header\n");
		return NULL;
	}

	// get To header from Notify
	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return NULL;
	}
	if( pto->tag_value.s ==NULL || pto->tag_value.len == 0){
		LM_ERR("reply without tag value \n");
	}
	LM_DBG("PTO: %.*s \n ", pto->uri.len, pto->uri.s );
	LM_DBG("PTO_TAG: %.*s \n ", pto->tag_value.len, pto->tag_value.s );
	LM_DBG("********************************************CALLID_STR%.*s\n", callid_event.len, callid_event.s);
	hash_code= core_hash(&callid_event, 0, subst_size);
	LM_DBG("********************************************HASH_CODE%d\n", hash_code);



	s= search_shtable(subs_htable, &callid, &pfrom->tag_value, hash_code, &method);
	if (s == NULL) {
		LM_ERR(" ---FAILURE SUB_CELL NOT FOUND IN SHTABLE\n");
	}

	return s;
}
Esempio n. 11
0
static void trace_sl_onreply_out( unsigned int types, struct sip_msg* req,
									struct sl_cb_param *sl_param)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
	int faked = 0;
	struct sip_msg* msg;
	int_str        avp_value;
	struct usr_avp *avp;
	struct ip_addr to_ip;
	int len;
	char statusbuf[5];

	if(req==NULL || sl_param==NULL)
	{
		LM_ERR("bad parameters\n");
		goto error;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) && trace_is_off(req))
	{
		LM_DBG("trace off...\n");
		return;
	}
	
	msg = req;
	faked = 1;
	
	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	db_vals[0].val.blob_val.s   = (sl_param->buffer)?sl_param->buffer->s:"";
	db_vals[0].val.blob_val.len = (sl_param->buffer)?sl_param->buffer->len:0;
	
	/* check Call-ID header */
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find Call-ID header!\n");
		goto error;
	}

	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	db_vals[2].val.str_val.s = msg->first_line.u.request.method.s;
	db_vals[2].val.str_val.len = msg->first_line.u.request.method.len;
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	if(trace_local_ip)
		db_vals[4].val.string_val = trace_local_ip;
	else {
		siptrace_copy_proto(msg->rcv.proto, fromip_buff);

		strcat(fromip_buff, ip_addr2a(&req->rcv.dst_ip));
		strcat(fromip_buff,":");
		strcat(fromip_buff, int2str(req->rcv.dst_port, NULL));
		db_vals[4].val.string_val = fromip_buff;
	}

	db_keys[3] = status_column;
	db_vals[3].type = DB_STRING;
	db_vals[3].nul = 0;
	strcpy(statusbuf, int2str(sl_param->code, NULL));
	db_vals[3].val.string_val = statusbuf;
		
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	memset(&to_ip, 0, sizeof(struct ip_addr));
	if(sl_param->dst==0)
	{
		db_vals[5].val.string_val = "any:255.255.255.255";
	} else {
		su2ip_addr(&to_ip, sl_param->dst);
		siptrace_copy_proto(req->rcv.proto, toip_buff);

		strcat(toip_buff, ip_addr2a(&to_ip));
		strcat(toip_buff, ":");
		strcat(toip_buff,
				int2str((unsigned long)su_getport(sl_param->dst), &len));
		LM_DBG("dest [%s]\n", toip_buff);
		db_vals[5].val.string_val = toip_buff;
	}
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "out";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());

	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if( !trace_is_off(msg) ) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		update_stat(siptrace_rpl, 1);
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("### - storing info (%d) ...\n", faked);
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}
	
done:
	return;
error:
	return;
}
Esempio n. 12
0
/* Get some fields necessary to pass in function_cb*/
int build_params_cb(struct sip_msg* msg, char* callidHeader,  struct parms_cb* params_cb ){

	char *dialog_aux;
	str from_tag;
	int size_callid;
	int size_dialog;
	char *dialog;

	if (parse_from_header(msg) != 0) {
		LM_ERR(" REQUEST WITHOUT FROM HEADER\n");
	}

	from_tag = get_from(msg)->tag_value;
	LM_DBG("FROM_TAG: %.*s\n", from_tag.len, from_tag.s);
	LM_DBG("CALLID = %s \n", callidHeader);

	size_callid = strlen(callidHeader);

	size_dialog= size_callid + from_tag.len + 26;
	dialog_aux = shm_malloc (sizeof (char)* size_dialog + 1);
	if (dialog_aux == NULL) {
		LM_ERR("--------------------------------------------------no more pkg memory\n");
		return 0;
	}

	memset(dialog_aux, 0, size_dialog + 1);
	dialog = dialog_aux;
	memcpy(dialog_aux, "dialog; call-id=", 16);
	dialog_aux += 16;
	memcpy(dialog_aux, callidHeader, size_callid);
	dialog_aux += size_callid;
	memcpy(dialog_aux, ";from-tag=", 10);
	dialog_aux += 10;
	memcpy(dialog_aux, from_tag.s, from_tag.len);
	LM_DBG("dialog: %s\n", dialog);


	char *call_aux = shm_malloc (size_callid + 1);
	if (call_aux == NULL) {
		LM_ERR("--------------------------------------------------no more pkg memory\n");
		return 0;
	}
	call_aux[size_callid] = 0;
	memcpy(call_aux, callidHeader, size_callid);

	char *ftag = shm_malloc (from_tag.len + 1);
	if (ftag == NULL) {
		LM_ERR("--------------------------------------------------no more pkg memory\n");
		return 0;
	}
	ftag[from_tag.len] = 0;
	memcpy(ftag, from_tag.s, from_tag.len);

	params_cb->callid_ori.s = call_aux;
	params_cb->callid_ori.len = size_callid;
	params_cb->from_tag.s = ftag;
	params_cb->from_tag.len = from_tag.len;
	params_cb->event.s = dialog;
	params_cb->event.len = size_dialog;

	return 1;

}
Esempio n. 13
0
void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps)
{
	struct sip_msg* msg= NULL;
	int lexpire= 0;
	unsigned int cseq;
	ua_pres_t* presentity= NULL, *hentity= NULL;
	struct to_body *pto= NULL, *pfrom = NULL;
	int size= 0;
	int flag ;
	str record_route= {0, 0};
	int rt;
	str contact;
	int initial_request = 0;

	if(ps==NULL || ps->param== NULL || *ps->param== NULL )
	{
		LM_ERR("null callback parameter\n");
		return;
	}
	LM_DBG("completed with status %d\n",ps->code) ;
	hentity= (ua_pres_t*)(*ps->param);
	flag= hentity->flag;
	if(hentity->flag & XMPP_INITIAL_SUBS)
		hentity->flag= XMPP_SUBSCRIBE;

	/* get dialog information from reply message: callid, to_tag, from_tag */
	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n ");
		goto error;
	}

	if(msg== FAKED_REPLY)
	{
		/* delete record from hash_table and call registered functions */

		if(hentity->call_id.s== NULL) /* if a new requets failed-> do nothing*/
		{
			LM_DBG("initial Subscribe request failed\n");
			goto done;
		}
		lock_get(&HashT->p_records[hentity->hash_index].lock);
		presentity = get_htable_safe(hentity->hash_index, hentity->local_index);
		if(presentity)
		{
			delete_htable_safe(presentity, hentity->hash_index);
			lock_release(&HashT->p_records[hentity->hash_index].lock);
		}
		lock_release(&HashT->p_records[hentity->hash_index].lock);
		goto done;
	}

	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("when parsing headers\n");
		goto done;
	}

	/*if initial request */

	if(hentity->call_id.s== NULL)
	{
		initial_request = 1;
		if(ps->code>= 300)
		{
			LM_DBG("initial Subscribe request failed\n");
			goto done;
		}

		if( msg->callid==NULL || msg->callid->body.s==NULL)
		{
			LM_ERR("cannot parse callid header\n");
			goto done;
		}

		if (!msg->from || !msg->from->body.s)
		{
			LM_ERR("cannot find 'from' header!\n");
			goto done;
		}
		if (msg->from->parsed == NULL)
		{
			if ( parse_from_header( msg )<0 ) 
			{
				LM_ERR("cannot parse From header\n");
				goto done;
			}
		}
		pfrom = (struct to_body*)msg->from->parsed;

		if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
		{
			LM_ERR("no from tag value present\n");
			goto done;
		}
		if( msg->to==NULL || msg->to->body.s==NULL)
		{
			LM_ERR("cannot parse TO header\n");
			goto done;
		}

		pto = get_to(msg);
		if (pto == NULL || pto->error != PARSE_OK) {
			LM_ERR("failed to parse TO header\n");
			goto done;
		}

		if( pto->tag_value.s ==NULL || pto->tag_value.len == 0)
		{
			LM_ERR("no to tag value present\n");
			goto done;
		}
		hentity->call_id=  msg->callid->body;
		hentity->to_tag= pto->tag_value;
		hentity->from_tag= pfrom->tag_value;

	}

	/* extract the other necesary information for inserting a new record */
	if(ps->rpl->expires && msg->expires->body.len > 0)
	{
		if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
		{
			LM_ERR("cannot parse Expires header\n");
			goto done;
		}
		lexpire = ((exp_body_t*)msg->expires->parsed)->val;
		LM_DBG("lexpire= %d\n", lexpire);
	}

	if(ps->code >= 300 )
	{	/* if an error code and a stored dialog delete it and try to send 
		   a subscription with type= INSERT_TYPE, else return*/

		if(!initial_request)
		{
			subs_info_t subs;

			lock_get(&HashT->p_records[hentity->hash_index].lock);
			presentity = get_htable_safe(hentity->hash_index, hentity->local_index);
			if(presentity)
			{
				hentity->event= presentity->event;
				delete_htable_safe(presentity, hentity->hash_index);
				lock_release(&HashT->p_records[hentity->hash_index].lock);
			}
			lock_release(&HashT->p_records[hentity->hash_index].lock);

			memset(&subs, 0, sizeof(subs_info_t));
			subs.pres_uri= hentity->pres_uri;
			subs.to_uri  = hentity->to_uri;
			subs.watcher_uri= hentity->watcher_uri;
			subs.contact= &hentity->contact;

			if(hentity->remote_contact.s)
				subs.remote_target= &hentity->remote_contact;

			if(hentity->desired_expires== 0)
				subs.expires= -1;
			else
			if(hentity->desired_expires< (int)time(NULL))
				subs.expires= 0;
			else
				subs.expires= hentity->desired_expires- (int)time(NULL)+ 3;

			subs.flag= INSERT_TYPE;
			subs.source_flag= flag;
			subs.event= hentity->event;
			subs.id= hentity->id;
			subs.outbound_proxy= hentity->outbound_proxy;
			subs.extra_headers= &hentity->extra_headers;
			subs.cb_param= hentity->cb_param;

			if(send_subscribe(&subs)< 0)
			{
				LM_ERR("when trying to send SUBSCRIBE\n");
				goto done;
			}
		}
		goto done;
	}
	/*if a 2XX reply handle the two cases- an existing dialog and a new one*/

	/* extract the contact */
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		goto error;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		goto error;
	}

	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		goto error;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	if(!initial_request)
	{
		/* do not delete the dialog - allow Notifies to be recognized as
		 * inside a known dialog */
	        if (lexpire == 0)
	                lexpire = 5;

		LM_DBG("*** Update expires\n");
		update_htable(hentity->hash_index, hentity->local_index, lexpire, NULL, &contact);
		goto done;
	}

	/* if a new dialog -> insert */
	if(lexpire== 0)
	{
		LM_DBG("expires= 0: no not insert\n");
		goto done;
	}

	if( msg->cseq==NULL || msg->cseq->body.s==NULL)
	{
		LM_ERR("cannot parse cseq header\n");
		goto done;
	}

	if( str2int( &(get_cseq(msg)->number), &cseq)< 0)
	{
		LM_ERR("while converting str to int\n");
		goto done;
    }

	/*process record route and add it to a string*/
	if (msg->record_route!=NULL)
	{
		rt = print_rr_body(msg->record_route, &record_route, 1, 0);
		if(rt != 0)
		{
			LM_ERR("parsing record route [%d]\n", rt);
			record_route.s=NULL;
			record_route.len=0;
		}
	}

	size= sizeof(ua_pres_t)+ 2*sizeof(str)+(hentity->pres_uri->len+ pto->uri.len+
		pfrom->uri.len+ pto->tag_value.len+ pfrom->tag_value.len
		+msg->callid->body.len+ record_route.len+ hentity->contact.len+
		hentity->id.len )*sizeof(char);

	presentity= (ua_pres_t*)shm_malloc(size);
	if(presentity== NULL)
	{
		LM_ERR("no more share memory\n");
		if(record_route.s)
			pkg_free(record_route.s);
		goto done;
	}
	memset(presentity, 0, size);
	size= sizeof(ua_pres_t);

	presentity->pres_uri= (str*)( (char*)presentity+ size);
	size+= sizeof(str);
	presentity->pres_uri->s= (char*)presentity+ size;
	memcpy(presentity->pres_uri->s, hentity->pres_uri->s, hentity->pres_uri->len);
	presentity->pres_uri->len= hentity->pres_uri->len;
	size+= hentity->pres_uri->len;

	presentity->to_uri.s= (char*)presentity+ size;
	memcpy(presentity->to_uri.s, pto->uri.s, pto->uri.len);
	presentity->to_uri.len= pto->uri.len;
	size+= pto->uri.len;

	presentity->watcher_uri= (str*)( (char*)presentity+ size);
	size+= sizeof(str);
	presentity->watcher_uri->s= (char*)presentity+ size;
	memcpy(presentity->watcher_uri->s, pfrom->uri.s, pfrom->uri.len);
	presentity->watcher_uri->len= pfrom->uri.len;
	size+= pfrom->uri.len;

	presentity->call_id.s= (char*)presentity + size;
	memcpy(presentity->call_id.s,msg->callid->body.s, 
		msg->callid->body.len);
	presentity->call_id.len= msg->callid->body.len;
	size+= presentity->call_id.len;

	presentity->to_tag.s= (char*)presentity + size;
	memcpy(presentity->to_tag.s,pto->tag_value.s, 
			pto->tag_value.len);
	presentity->to_tag.len= pto->tag_value.len;
	size+= pto->tag_value.len;

	presentity->from_tag.s= (char*)presentity + size;
	memcpy(presentity->from_tag.s,pfrom->tag_value.s, 
			pfrom->tag_value.len);
	presentity->from_tag.len= pfrom->tag_value.len;
	size+= pfrom->tag_value.len;

	if(record_route.len && record_route.s)
	{
		presentity->record_route.s= (char*)presentity + size;
		memcpy(presentity->record_route.s, record_route.s, record_route.len);
		presentity->record_route.len= record_route.len;
		size+= record_route.len;
		pkg_free(record_route.s);
	}


	presentity->contact.s= (char*)presentity + size;
	memcpy(presentity->contact.s, hentity->contact.s, hentity->contact.len);
	presentity->contact.len= hentity->contact.len;
	size+= hentity->contact.len;

	if(hentity->id.s)
	{
		presentity->id.s=(char*)presentity+ size;
		memcpy(presentity->id.s, hentity->id.s, 
			hentity->id.len);
		presentity->id.len= hentity->id.len; 
		size+= presentity->id.len;
	}

	if(hentity->extra_headers.s && hentity->extra_headers.len)
	{
		presentity->extra_headers.s= (char*)shm_malloc(hentity->extra_headers.len* sizeof(char));
		if(presentity->extra_headers.s== NULL)
		{
			LM_ERR("no more share memory\n");
			goto mem_error;
		}
		memcpy(presentity->extra_headers.s, hentity->extra_headers.s, hentity->extra_headers.len);
		presentity->extra_headers.len= hentity->extra_headers.len;
	}

	/* write the remote contact filed */
	presentity->remote_contact.s= (char*)shm_malloc(contact.len* sizeof(char));
	if(presentity->remote_contact.s== NULL)
	{
		LM_ERR("no more share memory\n");
		goto mem_error;
	}
	memcpy(presentity->remote_contact.s, contact.s, contact.len);
	presentity->remote_contact.len= contact.len;

	presentity->event|= hentity->event;
	presentity->flag= hentity->flag;
	presentity->etag.s= NULL;
	presentity->cseq= cseq;
	presentity->desired_expires= hentity->desired_expires;
	presentity->expires= lexpire+ (int)time(NULL);
	if(BLA_SUBSCRIBE & presentity->flag)
	{
		LM_DBG("BLA_SUBSCRIBE FLAG inserted\n");
	}
	LM_DBG("record for subscribe from %.*s to %.*s inserted in datatbase\n",
			presentity->watcher_uri->len, presentity->watcher_uri->s,
			presentity->pres_uri->len, presentity->pres_uri->s);
	insert_htable(presentity);

done:
	if(hentity->ua_flag == REQ_OTHER)
	{
		hentity->flag= flag;
		run_pua_callbacks( hentity, msg);
	}

error:
        if(hentity->extra_headers.s)
		shm_free(hentity->extra_headers.s);
	shm_free(hentity);
	return;

mem_error:
        if(presentity->extra_headers.s)
		shm_free(presentity->extra_headers.s);
        if(presentity->remote_contact.s)
                shm_free(presentity->remote_contact.s);
	shm_free(presentity);
        if(hentity->extra_headers.s)
		shm_free(hentity->extra_headers.s);
	shm_free(hentity);
}
Esempio n. 14
0
/* returns: 0/1 (false/true) or -1 on error, -127 EXPR_DROP */
static int eval_elem(struct expr* e, struct sip_msg* msg)
{

	struct sip_uri uri;
	int ret;
	ret=E_BUG;
	
	if (e->type!=ELEM_T){
		LOG(L_CRIT," BUG: eval_elem: invalid type\n");
		goto error;
	}
	switch(e->l.operand){
		case METHOD_O:
				ret=comp_strstr(&msg->first_line.u.request.method, e->r.param,
								e->op, e->subtype);
				break;
		case URI_O:
				if(msg->new_uri.s){
					if (e->subtype==MYSELF_ST){
						if (parse_sip_msg_uri(msg)<0) ret=-1;
						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
									msg->parsed_uri.port_no?
									msg->parsed_uri.port_no:SIP_PORT);
					}else{
						ret=comp_strstr(&msg->new_uri, e->r.param,
										e->op, e->subtype);
					}
				}else{
					if (e->subtype==MYSELF_ST){
						if (parse_sip_msg_uri(msg)<0) ret=-1;
						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
									msg->parsed_uri.port_no?
									msg->parsed_uri.port_no:SIP_PORT);
					}else{
						ret=comp_strstr(&msg->first_line.u.request.uri,
										 e->r.param, e->op, e->subtype);
					}
				}
				break;
		case FROM_URI_O:
				if (parse_from_header(msg)!=0){
					LOG(L_ERR, "ERROR: eval_elem: bad or missing"
								" From: header\n");
					goto error;
				}
				if (e->subtype==MYSELF_ST){
					if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len,
									&uri) < 0){
						LOG(L_ERR, "ERROR: eval_elem: bad uri in From:\n");
						goto error;
					}
					ret=check_self_op(e->op, &uri.host,
										uri.port_no?uri.port_no:SIP_PORT);
				}else{
					ret=comp_strstr(&get_from(msg)->uri,
							e->r.param, e->op, e->subtype);
				}
				break;
		case TO_URI_O:
				if ((msg->to==0) && ((parse_headers(msg, HDR_TO_F, 0)==-1) ||
							(msg->to==0))){
					LOG(L_ERR, "ERROR: eval_elem: bad or missing"
								" To: header\n");
					goto error;
				}
				/* to content is parsed automatically */
				if (e->subtype==MYSELF_ST){
					if (parse_uri(get_to(msg)->uri.s, get_to(msg)->uri.len,
									&uri) < 0){
						LOG(L_ERR, "ERROR: eval_elem: bad uri in To:\n");
						goto error;
					}
					ret=check_self_op(e->op, &uri.host,
										uri.port_no?uri.port_no:SIP_PORT);
				}else{
					ret=comp_strstr(&get_to(msg)->uri,
										e->r.param, e->op, e->subtype);
				}
				break;
		case SRCIP_O:
				ret=comp_ip(&msg->rcv.src_ip, e->r.param, e->op, e->subtype);
				break;
		case DSTIP_O:
				ret=comp_ip(&msg->rcv.dst_ip, e->r.param, e->op, e->subtype);
				break;
		case NUMBER_O:
				ret=!(!e->r.intval); /* !! to transform it in {0,1} */
				break;
		case ACTION_O:
				ret=run_action_list( (struct action*)e->r.param, msg);
				if (ret<=0) ret=(ret==0)?EXPR_DROP:0;
				else ret=1;
				break;
		case SRCPORT_O:
				ret=comp_no(msg->rcv.src_port, 
					e->r.param, /* e.g., 5060 */
					e->op, /* e.g. == */
					e->subtype /* 5060 is number */);
				break;
		case DSTPORT_O:
				ret=comp_no(msg->rcv.dst_port, e->r.param, e->op, 
							e->subtype);
				break;
		case PROTO_O:
				ret=comp_no(msg->rcv.proto, e->r.param, e->op, e->subtype);
				break;
		case AF_O:
				ret=comp_no(msg->rcv.src_ip.af, e->r.param, e->op, e->subtype);
				break;
		case RETCODE_O:
				ret=comp_no(return_code, e->r.param, e->op, e->subtype);
				break;
		case MSGLEN_O:
				ret=comp_no(msg->len, e->r.param, e->op, e->subtype);
				break;
		default:
				LOG(L_CRIT, "BUG: eval_elem: invalid operand %d\n",
							e->l.operand);
	}
	return ret;
error:
	return -1;
}
Esempio n. 15
0
/*Actions are composed as follows:
 * (the action length and type as always= 5 bytes)
 * 4:uac_id
 *
 * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp)
 * TODO performance speedup: instead of using
 * dynamically allocated memory for headers,body,totag,reason and my_msg
 * use static buffers.
 *
 */
int ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
{
   unsigned int cseq;
   char err_buf[MAX_REASON_LEN];
   struct sip_msg *my_msg;
   struct to_body *fb,*tb;
   struct cseq_body *cseqb;
   struct as_uac_param *the_param;
   dlg_t *my_dlg;
   int k,retval,uac_id,sip_error,ret,err_ret;
   long clen;
   str headers,body,fake_uri;
   uac_req_t uac_r;

   headers.s=body.s=fake_uri.s=NULL;
   my_dlg=NULL;
   my_msg=NULL;
   the_param=NULL;
   k=clen=0;

   net2hostL(uac_id,action,k);

   if(!(headers.s=pkg_malloc(MAX_HEADER))){
      LM_ERR("Out of Memory!!");
      goto error;
   }
   headers.len=0;
   LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id);
   if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
      LM_ERR("out of memory!\n");
      goto error;
   }
   if(my_msg->first_line.type==SIP_REPLY){
      LM_ERR("trying to create a UAC with a SIP response!!\n");
      goto error;
   }
   if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
      LM_ERR("ERROR:seas:ac_uac_req:parsing headers\n");
      goto error;
   }
   if(parse_from_header(my_msg)<0){
      LM_ERR("parsing from header ! \n");
      goto error;
   }
   if(check_transaction_quadruple(my_msg)==0){
      as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0);
      LM_ERR("Headers missing (to,from,call-id,cseq)?");
      goto error;
   }
   if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) || 
	 !(get_from(my_msg)->tag_value.len)){
      as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0);
      LM_ERR("From tag missing");
      goto error;
   }
   fb=my_msg->from->parsed;
   tb=my_msg->to->parsed;
   cseqb=my_msg->cseq->parsed;
   if(0!=(str2int(&cseqb->number,&cseq))){
      LM_DBG("unable to parse CSeq\n");
      goto error;
   }
   if(my_msg->first_line.u.request.method_value != METHOD_ACK &&
	 my_msg->first_line.u.request.method_value != METHOD_CANCEL) {
      /** we trick req_within */
      cseq--;
   }
   if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\
	    &(fb->uri),&(tb->uri),&my_dlg) < 0) {
      as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0);
      LM_ERR("Error while creating new dialog\n");
      goto error;
   }
   if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) {
      as_action_fail_resp(uac_id,SE_UAC,
         "Error adding the display names to the new dialog",0);
      LM_ERR("failed to add display names to the new dialog\n");
      goto error;
   }

   if(tb->tag_value.s && tb->tag_value.len)
      shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value);
   /**Awful hack: to be able to set our own CSeq, from_tag and call-ID we have
    * to use req_within instead of req_outside (it sets it's own CSeq,Call-ID
    * and ftag), so we have to simulate that the dialog is already in completed
    * state so...
    */
   server_signature=0;
   my_dlg->state = DLG_CONFIRMED;
   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))) {
      LM_ERR("Unable to extract allowed headers!!\n");
      goto error;
   }
   headers.s[headers.len]=0;
   /*let's get the body*/
   if(my_msg->content_length)
      clen=(long)get_content_length(my_msg);
   if(clen!=0){
      if(!(body.s=pkg_malloc(clen))){
	 LM_ERR("Out of Memory!");
	 goto error;
      }
      memcpy(body.s,get_body(my_msg),clen);
      body.len=clen;
      body.s[clen]=0;
      LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\
	    body.len,body.len,body.s,headers.len,headers.len,headers.s);
      /*t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
   }else{
      body.s=NULL;
      body.len=0;
   }
   /*Now... create the UAC !!
    * it would be great to know the hash_index and the label that have been assigned
    * to our newly created cell, but t_uac does not leave any way for us to know...
    * only that when that transaction transitions its state (ie. a response is received,
    * a timeout is reached, etc...) the callback will be called with the given parameter.
    *
    * So the only way we have to know who we are, is passing as a parameter a structure with
    * 2 pointers: one to the app_server and the other, the identifier of the UAC (uac_id).
    *
    */
   if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
      LM_ERR("out of shared memory\n");
      goto error;
   }
   the_param->who=my_as;
   the_param->uac_id=uac_id;
   the_param->processor_id=processor_id;
   the_param->destroy_cb_set=0;

   shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri);

   if (my_msg->route) {
      if (parse_rr(my_msg->route) < 0) {
	 LM_ERR( "Error while parsing Route body\n");
	 goto error;
      }
      /* TODO route_set should be a shm copy of my_msg->route->parsed */
      my_dlg->route_set=(rr_t*)my_msg->route->parsed;
      /** this SHOULD be:
       shm_duplicate_rr(&my_dlg->route_set,my_msg->route->parsed);
       * but it will last more...
       */
   }
   calculate_hooks(my_dlg);
   if(flags & SPIRAL_FLAG){
      memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
      headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
      headers.s[headers.len]=0;
      fake_uri.s=pkg_malloc(200);
      fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);

      if(fake_uri.len<0){
	 LM_ERR("printing local uri\n");
	 goto error;
      }
      my_dlg->hooks.next_hop=&fake_uri;
   }
   /* Kamailio and OpenSIPs seem to have diverged quite a bit on flags and events
      notified to UACs. Let's see if kamailio gets it right by now, if not
      this is a TODO: check PASS_PROVISIONAL
      my_dlg->T_flags=T_NO_AUTO_ACK|T_PASS_PROVISIONAL_FLAG ;
      this is the same as (TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT) in Kamailio
   */

   set_uac_req(&uac_r, &(my_msg->first_line.u.request.method), &headers,
		   &body, my_dlg,TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT, uac_cb,
		   (void*)the_param);

   ret=seas_f.tmb.t_request_within(&uac_r);

   /** now undo all the fakes we have put in my_dlg*/
   /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/
   my_dlg->route_set=(rr_t *)0;
   if (ret < 0) {
      err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
      LM_ERR("failed to send the [%.*s] request\n",uac_r.method->len,uac_r.method->s);
      LM_ERR("Error on request_within %s\n",err_buf );
      if(err_ret > 0) {
	 as_action_fail_resp(uac_id,ret,err_buf,0);
      }else{
	 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
      }
      goto error;
   }
   retval=0;
   goto exit;
error:
   retval = -1;
   if(the_param)
      shm_free(the_param);
exit:
   seas_f.tmb.free_dlg(my_dlg);
   if(headers.s)
      pkg_free(headers.s);
   if(body.s)
      pkg_free(body.s);
   if(fake_uri.s)
      pkg_free(fake_uri.s);
   if(my_msg){
      if(my_msg->headers)
	 free_hdr_field_lst(my_msg->headers);
      pkg_free(my_msg);
   }
   return retval;
}
Esempio n. 16
0
static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];

	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
	struct sip_msg* msg;
	struct sip_msg* req;
	int_str        avp_value;
	struct usr_avp *avp;
	char statusbuf[8];
	
	if(t==NULL || t->uas.request==0 || ps==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return;
	}

	req = ps->req;
	msg = ps->rpl;
	if(msg==NULL || req==NULL)
	{
		LM_DBG("no reply\n");
		return;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) &&  trace_is_off(req))
	{
		LM_DBG("trace off...\n");
		return;
	}

	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	if(msg->len>0) {
		db_vals[0].val.blob_val.s   = msg->buf;
		db_vals[0].val.blob_val.len = msg->len;
	} else {
		db_vals[0].val.blob_val.s   = "No reply buffer";
		db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
	}

	/* check Call-ID header */
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find Call-ID header!\n");
		goto error;
	}

	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	db_vals[2].val.str_val.s = t->method.s;
	db_vals[2].val.str_val.len = t->method.len;
		
	db_keys[3] = status_column;
	db_vals[3].type = DB_STRING;
	db_vals[3].nul = 0;
	strcpy(statusbuf, int2str(ps->code, NULL));
	db_vals[3].val.string_val = statusbuf;
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	siptrace_copy_proto(msg->rcv.proto, fromip_buff);
	strcat(fromip_buff, ip_addr2a(&msg->rcv.src_ip));
	strcat(fromip_buff,":");
	strcat(fromip_buff, int2str(msg->rcv.src_port, NULL));
	db_vals[4].val.string_val = fromip_buff;
	
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	// db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);;
	if(trace_local_ip)
		db_vals[5].val.string_val = trace_local_ip;
	else {
		siptrace_copy_proto(msg->rcv.proto, toip_buff);
		strcat(toip_buff, ip_addr2a(&msg->rcv.dst_ip));
		strcat(toip_buff,":");
		strcat(toip_buff, int2str(msg->rcv.dst_port, NULL));
		db_vals[5].val.string_val = toip_buff;
	}
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "in";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());

	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if( !trace_is_off(req) ) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		update_stat(siptrace_rpl, 1);
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("storing info ...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}
	
done:
	return;
error:
	return;
}
Esempio n. 17
0
/**
 * store message
 * mode = "0" -- look for outgoing URI starting with new_uri
 * 		= "1" -- look for outgoing URI starting with r-uri
 * 		= "2" -- look for outgoing URI only at to header
 */
static int m_store(struct sip_msg* msg, char* mode, char* str2)
{
	str body, str_hdr, sruri, ctaddr;
	struct to_body to, *pto, *pfrom;
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	int nr_keys = 0, val, lexpire;
	t_content_type ctype;
	char buf[512], buf1[1024], *p;
	int mime;

	DBG("MSILO: m_store: ------------ start ------------\n");

	// extract message body - after that whole SIP MESSAGE is parsed
	/* get the message's body */
	body.s = get_body( msg );
	if (body.s==0) 
	{
		LOG(L_ERR,"MSILO:m_store: ERROR cannot extract body from msg\n");
		goto error;
	}
	
	/* content-length (if present) must be already parsed */
	if (!msg->content_length) 
	{
		LOG(L_ERR,"MSILO:m_store: ERROR no Content-Length header found!\n");
		goto error;
	}
	body.len = get_content_length( msg );

	// check if the body of message contains something
	if(body.len <= 0)
	{
		DBG("MSILO:m_store: body of the message is empty!\n");
		goto error;
	}
	
	// check TO header
	if(!msg->to || !msg->to->body.s)
	{
		DBG("MSILO:m_store: cannot find 'to' header!\n");
		goto error;
	}

	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		DBG("MSILO:m_store: 'To' header ALREADY PARSED: <%.*s>\n",
			pto->uri.len, pto->uri.s );	
	}
	else
	{
		DBG("MSILO:m_store: 'To' header NOT PARSED ->parsing ...\n");
		memset( &to , 0, sizeof(to) );
		parse_to(msg->to->body.s, msg->to->body.s+msg->to->body.len+1, &to);
		if(to.uri.len > 0) // && to.error == PARSE_OK)
		{
			DBG("MSILO:m_store: 'To' parsed OK <%.*s>.\n", 
				to.uri.len, to.uri.s);
			pto = &to;
		}
		else
		{
			DBG("MSILO:m_store: ERROR 'To' cannot be parsed\n");
			goto error;
		}
	}
	
	if(pto->uri.len == reg_addr.len && 
			!strncasecmp(pto->uri.s, reg_addr.s, reg_addr.len))
	{
		DBG("MSILO:m_store: message to MSILO REGISTRAR!\n");
		goto error;
	}

	db_keys[nr_keys] = DB_KEY_TO;
	
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = pto->uri.s;
	db_vals[nr_keys].val.str_val.len = pto->uri.len;

	nr_keys++;

	// check FROM header
	if(!msg->from || !msg->from->body.s)
	{
		DBG("MSILO:m_store: ERROR cannot find 'from' header!\n");
		goto error;
	}

	if(msg->from->parsed != NULL)
		DBG("MSILO:m_store: 'From' header ALREADY PARSED\n");	
	else
	{
		DBG("MSILO:m_store: 'From' header NOT PARSED\n");
		/* parsing from header */
		if ( parse_from_header( msg )==-1 ) 
		{
			DBG("MSILO:m_store: ERROR cannot parse FROM header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	DBG("MSILO:m_store: 'From' header: <%.*s>\n",pfrom->uri.len,pfrom->uri.s);	
	
	if(reg_addr.s && pfrom->uri.len == reg_addr.len && 
			!strncasecmp(pfrom->uri.s, reg_addr.s, reg_addr.len))
	{
		DBG("MSILO:m_store: message from MSILO REGISTRAR!\n");
		goto error;
	}

	db_keys[nr_keys] = DB_KEY_FROM;
	
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = pfrom->uri.s;
	db_vals[nr_keys].val.str_val.len = pfrom->uri.len;

	nr_keys++;

	// chech for RURI
	sruri.len = 0;
	if(mode && mode[0]=='0' && msg->new_uri.len > 0)
	{
		DBG("MSILO:m_store: NEW R-URI found - check if is AoR!\n");
		p = msg->new_uri.s;
		while((p < msg->new_uri.s+msg->new_uri.len) && *p!='@')
			p++;
		if(p < msg->new_uri.s+msg->new_uri.len && p > msg->new_uri.s)
		{
			DBG("MSILO:m_store: NEW R-URI used\n");
			sruri.s = msg->new_uri.s;
			// check for parameters
			while((p < msg->new_uri.s+msg->new_uri.len) && *p!=';')
				p++;
			sruri.len = p - msg->new_uri.s;
		}
	}
	
	if(mode && mode[0]<='1' && sruri.len == 0 
			&& msg->first_line.u.request.uri.len > 0 )
	{
		DBG("MSILO:m_store: R-URI found - check if is AoR!\n");
		p = msg->first_line.u.request.uri.s;
		while((p < msg->first_line.u.request.uri.s+
				msg->first_line.u.request.uri.len) && *p!='@')
			p++;
		if(p<msg->first_line.u.request.uri.s+msg->first_line.u.request.uri.len
			&& p > msg->first_line.u.request.uri.s)
		{
			DBG("MSILO:m_store: R-URI used\n");
			sruri.s = msg->first_line.u.request.uri.s;
			// check for parameters
			while((p < msg->first_line.u.request.uri.s
					+ msg->first_line.u.request.uri.len) && *p!=';')
				p++;
			sruri.len = p - msg->first_line.u.request.uri.s;
		}
	}
	
	if (sruri.len == 0)
	{
		DBG("MSILO:m_store: TO used as R-URI\n");
		sruri.s = pto->uri.s;
		sruri.len = pto->uri.len;
	}
	
	db_keys[nr_keys] = DB_KEY_RURI;
	
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = sruri.s;
	db_vals[nr_keys].val.str_val.len = sruri.len;

	nr_keys++;

	/* add the message's body in SQL query */
	
	db_keys[nr_keys] = DB_KEY_BODY;
	
	db_vals[nr_keys].type = DB_BLOB;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.blob_val.s = body.s;
	db_vals[nr_keys].val.blob_val.len = body.len;

	nr_keys++;
	
	lexpire = expire_time;
	// add 'content-type'
	/* parse the content-type header */
	if ((mime=parse_content_type_hdr(msg))<1 ) 
	{
		LOG(L_ERR,"MSILO:m_store: ERROR cannot parse Content-Type header\n");
		goto error;
	}

	/** check the content-type value */
	if( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
		&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM )
	{
		if(m_extract_content_type(msg->content_type->body.s, 
				msg->content_type->body.len, &ctype, CT_TYPE) != -1)
		{
			DBG("MSILO:m_store: 'content-type' found\n");
			db_keys[nr_keys] = DB_KEY_CTYPE;
			db_vals[nr_keys].type = DB_STR;
			db_vals[nr_keys].nul = 0;
			db_vals[nr_keys].val.str_val.s = ctype.type.s;
			db_vals[nr_keys].val.str_val.len = ctype.type.len;
			nr_keys++;
		}
	}

	// check 'expires'
	// no more parseing - already done by get_body()
	// if(parse_headers(msg, HDR_EXPIRES,0)!=-1)
	if(msg->expires && msg->expires->body.len > 0)
	{
		DBG("MSILO:m_store: 'expires' found\n");
		val = atoi(msg->expires->body.s);
		if(val > 0)
			lexpire = (expire_time<=val)?expire_time:val;
	}

	/** current time */
	val = (int)time(NULL);
	
	/** add expiration time */
	db_keys[nr_keys] = DB_KEY_EXP_TIME;
	db_vals[nr_keys].type = DB_INT;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.int_val = val+lexpire;
	nr_keys++;

	/** add incoming time */
	db_keys[nr_keys] = DB_KEY_INC_TIME;
	db_vals[nr_keys].type = DB_INT;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.int_val = val;
	nr_keys++;

	if(db_insert(db_con, db_keys, db_vals, nr_keys) < 0)
	{
		LOG(L_ERR, "MSILO:m_store: error storing message\n");
		goto error;
	}
	DBG("MSILO:m_store: message stored. T:<%.*s> F:<%.*s>\n",
		pto->uri.len, pto->uri.s, pfrom->uri.len, pfrom->uri.s);
	if(reg_addr.len > 0 && reg_addr.len+33+2*CRLF_LEN < 1024)
	{
		DBG("MSILO:m_store: sending info message.\n");
		strcpy(buf1,"Content-Type: text/plain"CRLF"Contact: ");
		str_hdr.len = 24 + CRLF_LEN + 9;
		strncat(buf1,reg_addr.s,reg_addr.len);
		str_hdr.len += reg_addr.len;
		strcat(buf1, CRLF);
		str_hdr.len += CRLF_LEN;
		str_hdr.s = buf1;
	
		strncpy(buf, "User [", 6);
		body.len = 6;
		if(pto->uri.len+75 < 512)
		{
			strncpy(buf+body.len, pto->uri.s, pto->uri.len);
			body.len += pto->uri.len;
		}
		strncpy(buf+body.len, "] is offline.", 13);
		body.len += 12;
		strncpy(buf+body.len, " The message will be delivered", 30);
		body.len += 30;
		strncpy(buf+body.len, " when user goes online.", 23);
		body.len += 23;

		body.s = buf;

		// look for Contact header
		ctaddr.s = NULL;
		if(use_contact && parse_headers(msg,HDR_CONTACT,0)!=-1 && msg->contact
				&& msg->contact->body.s && msg->contact->body.len>0)
		{
			ctaddr.s = msg->contact->body.s;
			ctaddr.len = msg->contact->body.len;
			p = ctaddr.s;
			while(p<ctaddr.s+ctaddr.len && *p!='<')
				p++;
			if(*p == '<')
			{
				p++;
				ctaddr.s = p;
				while(p<ctaddr.s+ctaddr.len && *p!='>')
						p++;
				if(p<ctaddr.s+ctaddr.len)
					ctaddr.len = p-ctaddr.s;
			}
			if(!ctaddr.s || ctaddr.len < 6 || strncmp(ctaddr.s, "sip:", 4)
				|| ctaddr.s[4]==' ')
				ctaddr.s = NULL;
			else
				DBG("MSILO:m_store: feedback contact [%.*s]\n",
							ctaddr.len,ctaddr.s);
		}
		
		// tmb.t_uac(&msg_type,&pfrom->uri,&str_hdr,&body,&reg_addr,0,0,0);
		tmb.t_request(&msg_type,  /* Type of the message */
				(ctaddr.s)?&ctaddr:&pfrom->uri,    /* Request-URI */
				&pfrom->uri,      /* To */
				&reg_addr,        /* From */
				&str_hdr,         /* Optional headers including CRLF */
				&body,            /* Message body */
				NULL,             /* Callback function */
				NULL              /* Callback parameter */
			);
	}
	
	return 1;
error:
	return -1;
}
Esempio n. 18
0
static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps)
{
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	int faked = 0;
	static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
	static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
	struct sip_msg* msg;
	struct sip_msg* req;
	int_str        avp_value;
	struct usr_avp *avp;
	struct ip_addr to_ip;
	int len;
	char statusbuf[8];
	str *sbuf;
	struct dest_info *dst;

	if (t==NULL || t->uas.request==0 || ps==NULL)
	{
		LM_DBG("no uas request, local transaction\n");
		return;
	}
	
	avp = NULL;
	if(traced_user_avp.n!=0)
		avp=search_first_avp(traced_user_avp_type, traced_user_avp,
				&avp_value, 0);

	if((avp==NULL) &&  trace_is_off(t->uas.request))
	{
		LM_DBG("trace off...\n");
		return;
	}
	
	req = ps->req;
	msg = ps->rpl;
	if(msg==NULL || msg==FAKED_REPLY)
	{
		msg = t->uas.request;
		faked = 1;
	}

	if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL)
	{
		LM_ERR("cannot parse FROM header\n");
		goto error;
	}

	if(parse_headers(msg, HDR_CALLID_F, 0)!=0)
	{
		LM_ERR("cannot parse call-id\n");
		return;
	}

	db_keys[0] = msg_column;
	db_vals[0].type = DB_BLOB;
	db_vals[0].nul = 0;
	sbuf = (str*)ps->extra1;
	if(faked==0)
	{
		if(sbuf!=0 && sbuf->len>0) {
			db_vals[0].val.blob_val.s   = sbuf->s;
			db_vals[0].val.blob_val.len = sbuf->len;
		} else if(t->uas.response.buffer.s!=NULL) {
			db_vals[0].val.blob_val.s   = t->uas.response.buffer.s;
			db_vals[0].val.blob_val.len = t->uas.response.buffer.len;
		} else if(msg->len>0) {
			db_vals[0].val.blob_val.s   = msg->buf;
			db_vals[0].val.blob_val.len = msg->len;
		} else {
			db_vals[0].val.blob_val.s   = "No reply buffer";
			db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
		}
	} else {
		if(sbuf!=0 && sbuf->len>0) {
			db_vals[0].val.blob_val.s   = sbuf->s;
			db_vals[0].val.blob_val.len = sbuf->len;
		} else if(t->uas.response.buffer.s==NULL) {
			db_vals[0].val.blob_val.s = "No reply buffer";
			db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
		} else {
			db_vals[0].val.blob_val.s = t->uas.response.buffer.s;
			db_vals[0].val.blob_val.len = t->uas.response.buffer.len;
		}
	}
	
	/* check Call-ID header */
	if(msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot find Call-ID header!\n");
		goto error;
	}

	db_keys[1] = callid_column;
	db_vals[1].type = DB_STR;
	db_vals[1].nul = 0;
	db_vals[1].val.str_val.s = msg->callid->body.s;
	db_vals[1].val.str_val.len = msg->callid->body.len;
	
	db_keys[2] = method_column;
	db_vals[2].type = DB_STR;
	db_vals[2].nul = 0;
	db_vals[2].val.str_val.s = t->method.s;
	db_vals[2].val.str_val.len = t->method.len;
		
	db_keys[4] = fromip_column;
	db_vals[4].type = DB_STRING;
	db_vals[4].nul = 0;
	
	if(trace_local_ip)
		db_vals[4].val.string_val = trace_local_ip;
	else {
		siptrace_copy_proto(msg->rcv.proto, fromip_buff);

		strcat(fromip_buff, ip_addr2a(&req->rcv.dst_ip));
		strcat(fromip_buff,":");
		strcat(fromip_buff, int2str(req->rcv.dst_port, NULL));
		db_vals[4].val.string_val = fromip_buff;
	}
	
	db_keys[3] = status_column;
	db_vals[3].type = DB_STRING;
	db_vals[3].nul = 0;
	strcpy(statusbuf, int2str(ps->code, NULL));
	db_vals[3].val.string_val = statusbuf;
		
	db_keys[5] = toip_column;
	db_vals[5].type = DB_STRING;
	db_vals[5].nul = 0;
	memset(&to_ip, 0, sizeof(struct ip_addr));
	dst = (struct dest_info*)ps->extra2;
	if(dst==0)
	{
		db_vals[5].val.string_val = "any:255.255.255.255";
	} else {
		su2ip_addr(&to_ip, &dst->to);
		siptrace_copy_proto(dst->proto, toip_buff);
		strcat(toip_buff, ip_addr2a(&to_ip));
		strcat(toip_buff, ":");
		strcat(toip_buff,
				int2str((unsigned long)su_getport(&dst->to), &len));
		LM_DBG("dest [%s]\n", toip_buff);
		db_vals[5].val.string_val = toip_buff;
	}
	
	db_keys[6] = date_column;
	db_vals[6].type = DB_DATETIME;
	db_vals[6].nul = 0;
	db_vals[6].val.time_val = time(NULL);
	
	db_keys[7] = direction_column;
	db_vals[7].type = DB_STRING;
	db_vals[7].nul = 0;
	db_vals[7].val.string_val = "out";
	
	db_keys[8] = fromtag_column;
	db_vals[8].type = DB_STR;
	db_vals[8].nul = 0;
	db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
	db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
	
	db_funcs.use_table(db_con, siptrace_get_table());

	db_keys[9] = traced_user_column;
	db_vals[9].type = DB_STR;
	db_vals[9].nul = 0;

	if( !trace_is_off(req) ) {
		db_vals[9].val.str_val.s   = "";
		db_vals[9].val.str_val.len = 0;
	
		LM_DBG("storing info...\n");
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
#ifdef STATISTICS
		update_stat(siptrace_rpl, 1);
#endif
	}
	
	if(avp==NULL)
		goto done;
	
	trace_send_duplicate(db_vals[0].val.blob_val.s,
			db_vals[0].val.blob_val.len);
	
	db_vals[9].val.str_val.s = avp_value.s.s;
	db_vals[9].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info...\n");
	if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
	{
		LM_ERR("error storing trace\n");
		goto error;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		db_vals[9].val.str_val.s = avp_value.s.s;
		db_vals[9].val.str_val.len = avp_value.s.len;

		LM_DBG("### - storing info (%d) ...\n", faked);
		if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			goto error;
		}
		avp = search_next_avp( avp, &avp_value);
	}
	
done:
	return;
error:
	return;
}
Esempio n. 19
0
/*
 * determines the permission of the call
 * return values:
 * -1:	deny
 * 1:	allow
 */
static int check_routing(struct sip_msg* msg, int idx)
{
	struct hdr_field *from;
	int len, q;
	static char from_str[EXPRESSION_LENGTH+1];
	static char ruri_str[EXPRESSION_LENGTH+1];
	char* uri_str;
	str branch;
	int br_idx;

	/* turn off control, allow any routing */
	if ((!allow[idx].rules) && (!deny[idx].rules)) {
		LM_DBG("no rules => allow any routing\n");
		return 1;
	}

	/* looking for FROM HF */
	if ((!msg->from) && (parse_headers(msg, HDR_FROM_F, 0) == -1)) {
		LM_ERR("failed to parse message\n");
		return -1;
	}

	if (!msg->from) {
		LM_ERR("FROM header field not found\n");
		return -1;
	}

	/* we must call parse_from_header explicitly */
	if ((!(msg->from)->parsed) && (parse_from_header(msg) < 0)) {
		LM_ERR("failed to parse From body\n");
		return -1;
	}

	from = msg->from;
	len = ((struct to_body*)from->parsed)->uri.len;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("From header field is too long: %d chars\n", len);
		return -1;
	}
	strncpy(from_str, ((struct to_body*)from->parsed)->uri.s, len);
	from_str[len] = '\0';

	/* looking for request URI */
	if (parse_sip_msg_uri(msg) < 0) {
		LM_ERR("uri parsing failed\n");
		return -1;
	}

	len = msg->parsed_uri.user.len + msg->parsed_uri.host.len + 5;
	if (len > EXPRESSION_LENGTH) {
		LM_ERR("Request URI is too long: %d chars\n", len);
		return -1;
	}

	strcpy(ruri_str, "sip:");
	memcpy(ruri_str + 4, msg->parsed_uri.user.s, msg->parsed_uri.user.len);
	ruri_str[msg->parsed_uri.user.len + 4] = '@';
	memcpy(ruri_str + msg->parsed_uri.user.len + 5, msg->parsed_uri.host.s, msg->parsed_uri.host.len);
	ruri_str[len] = '\0';

	LM_DBG("looking for From: %s Request-URI: %s\n", from_str, ruri_str);
	/* rule exists in allow file */
	if (search_rule(allow[idx].rules, from_str, ruri_str)) {
		if (check_all_branches) goto check_branches;
		LM_DBG("allow rule found => routing is allowed\n");
		return 1;
	}

	/* rule exists in deny file */
	if (search_rule(deny[idx].rules, from_str, ruri_str)) {
		LM_DBG("deny rule found => routing is denied\n");
		return -1;
	}

	if (!check_all_branches) {
		LM_DBG("neither allow nor deny rule found => routing is allowed\n");
		return 1;
	}

check_branches:
	for( br_idx=0 ; (branch.s=get_branch(br_idx,&branch.len,&q,0,0,0,0,0,0,0))!=0 ;
			br_idx++ ) {
		uri_str = get_plain_uri(&branch);
		if (!uri_str) {
			LM_ERR("failed to extract plain URI\n");
			return -1;
		}
		LM_DBG("looking for From: %s Branch: %s\n", from_str, uri_str);

		if (search_rule(allow[idx].rules, from_str, uri_str)) {
			continue;
		}

		if (search_rule(deny[idx].rules, from_str, uri_str)) {
			LM_DBG("deny rule found for one of branches => routing"
					"is denied\n");
			return -1;
		}
	}

	LM_DBG("check of branches passed => routing is allowed\n");
	return 1;
}
Esempio n. 20
0
/* get data from Subscriber and save in list link with notify information:
   . dialog id of emergency call
   . dialog id of subscribe
   . local uri
   . remote uri
   . contact
   . expires
   . time to expire subscriber
   - status
   . cell next
   . cell previus
   */
struct sm_subscriber* build_notify_cell(struct sip_msg *msg, int expires){

	char *subs_callid, *subs_fromtag;
	str callid_event;
	str fromtag_event;
	str callid;
	struct to_body *pto= NULL, *pfrom = NULL;
	int size_notify_cell;
	int vsp_addr_len;
	char *vsp_addr = "@vsp.com";
	int vsp_port = 5060;
	int size_vsp_port = 4;
	char* str_vsp_port;
	struct sm_subscriber *notify_cell = NULL;
	time_t rawtime;
	int time_now;
	char *p;
	unsigned int hash_code;
	static str msg489={"Bad Event",sizeof("Bad Event")-1};


	// get data from SUBSCRIBE request
	// get callid from Subscribe
	if( msg->callid==NULL || msg->callid->body.s==NULL){
		LM_ERR("subscribe without callid header\n");
		return NULL;
	}
	callid = msg->callid->body;
	LM_DBG("CALLID: %.*s \n ", callid.len, callid.s );

	//get From header from Subscribe
	if (msg->from->parsed == NULL){
		if ( parse_from_header( msg )<0 ){
			LM_ERR("subscribe without From header\n");
			return NULL;
		}
	}
	pfrom = get_from(msg);
	LM_DBG("PFROM: %.*s \n ", pfrom->uri.len, pfrom->uri.s );
	LM_DBG("PFROM_TAG: %.*s \n ", pfrom->tag_value.len, pfrom->tag_value.s );
	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0){
		LM_ERR("subscribe without from_tag value \n");
		return NULL;
	}
	if( msg->to==NULL || msg->to->body.s==NULL){
		LM_ERR("error in parse TO header\n");
		return NULL;
	}

	// get To header from Subscribe
	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return NULL;
	}

	LM_DBG("PTO: %.*s \n ", pto->uri.len, pto->uri.s );
	LM_DBG("PTO_TAG: %.*s \n ", pto->tag_value.len, pto->tag_value.s );

	/* get in event header: callid and from_tag */
	if(get_event_header(msg, &subs_callid, &subs_fromtag) != 1){
		LM_ERR("failed to parse Event header\n");
		return NULL;
	}

	LM_DBG("SUBS_CALLID: %s\n ", subs_callid);
	LM_DBG("SUBS_FROMTAG: %s\n ", subs_fromtag);
	callid_event.s = subs_callid;
	callid_event.len = strlen(subs_callid);
	fromtag_event.s = subs_fromtag;
	fromtag_event.len = strlen(subs_fromtag);

	hash_code= core_hash(&callid_event, 0, emet_size);
	LM_DBG("********************************************HASH_CODE%d\n", hash_code);

	// search call hash with hash_code, callidHeader and from/to_tag params
	if (search_ehtable(call_htable, subs_callid, subs_fromtag, hash_code, 0) == NULL) {
		LM_ERR(" ---CALLID NOT FOUND IN SHTABLE\n");
		if(!eme_tm.t_reply(msg,489,&msg489)){
			LM_DBG("t_reply (489)\n");
		}
		pkg_free(callid_event.s);
		pkg_free(fromtag_event.s);
		return 0;
	}
	LM_DBG("CALLID OK in subs_hash\n");

	time(&rawtime);
	time_now = (int)rawtime;
	LM_DBG("TIME : %d \n", (int)rawtime );

	// get source ip address that send INVITE
	vsp_addr = ip_addr2a(&msg->rcv.src_ip);
	vsp_addr_len = strlen(vsp_addr);
	vsp_port = msg->rcv.src_port;
	str_vsp_port= int2str(vsp_port, &size_vsp_port);
	LM_DBG("SRC_PORT : %s \n", str_vsp_port);

	/* build notifier cell */
	size_notify_cell = sizeof(struct sm_subscriber) + (2 * sizeof(struct dialog_id))
		+ callid.len + pfrom->tag_value.len + pto->tag_value.len + pfrom->uri.len + pto->uri.len
		+ callid_event.len +  fromtag_event.len + vsp_addr_len + size_vsp_port + 11  ;
	notify_cell = pkg_malloc(size_notify_cell + 1);
	if (!notify_cell) {
		LM_ERR("no more shm\n");
		return NULL;
	}

	memset(notify_cell, 0, size_notify_cell + 1);
	notify_cell->expires = expires;
	LM_DBG("EXPIRES: %d \n ", notify_cell->expires );
	notify_cell->timeout =  TIMER_N + time_now;
	LM_DBG("SUBS_TIMEOUT: %d \n ", notify_cell->timeout );
	notify_cell->version =  0;
	LM_DBG("SUBS_VERSION: %d \n ", notify_cell->version );

	notify_cell->dlg_id = (struct dialog_id*)(notify_cell + 1);

	notify_cell->dlg_id->callid.len = callid.len;
	notify_cell->dlg_id->callid.s = (char *) (notify_cell->dlg_id + 1);
	memcpy(notify_cell->dlg_id->callid.s, callid.s, callid.len);
	LM_DBG("SUBS_CALLID: %.*s \n ", notify_cell->dlg_id->callid.len, notify_cell->dlg_id->callid.s );

	notify_cell->dlg_id->rem_tag.len = pfrom->tag_value.len;
	notify_cell->dlg_id->rem_tag.s = (char *) (notify_cell->dlg_id + 1) + callid.len;
	memcpy(notify_cell->dlg_id->rem_tag.s, pfrom->tag_value.s, pfrom->tag_value.len);
	LM_DBG("SUBS_FROM_TAG: %.*s \n ", notify_cell->dlg_id->rem_tag.len, notify_cell->dlg_id->rem_tag.s );

	p = (char *)(notify_cell->dlg_id + 1) + callid.len + pfrom->tag_value.len;
	notify_cell->call_dlg_id = (struct dialog_id*)p;

	notify_cell->call_dlg_id->callid.len= callid_event.len;
	notify_cell->call_dlg_id->callid.s = (char *) (notify_cell->call_dlg_id + 1);
	memcpy(notify_cell->call_dlg_id->callid.s, callid_event.s, callid_event.len);
	LM_DBG("SUBS_CALLID_event: %.*s \n ", notify_cell->call_dlg_id->callid.len, notify_cell->call_dlg_id->callid.s );

	notify_cell->call_dlg_id->rem_tag.len= fromtag_event.len;
	notify_cell->call_dlg_id->rem_tag.s = (char *) (notify_cell->call_dlg_id + 1) + callid_event.len;
	memcpy(notify_cell->call_dlg_id->rem_tag.s, fromtag_event.s, fromtag_event.len);
	LM_DBG("SUBS_FROMTAG_event: %.*s \n ", notify_cell->call_dlg_id->rem_tag.len, notify_cell->call_dlg_id->rem_tag.s );

	notify_cell->loc_uri.len = pto->uri.len;
	notify_cell->loc_uri.s = (char *) (notify_cell->call_dlg_id + 1) + callid_event.len + fromtag_event.len;
	memcpy(notify_cell->loc_uri.s,pto->uri.s,pto->uri.len);
	LM_DBG("SUBS_LOC_URI: %.*s \n ", notify_cell->loc_uri.len, notify_cell->loc_uri.s );

	notify_cell->rem_uri.len= pfrom->uri.len;
	notify_cell->rem_uri.s = (char *) (notify_cell->call_dlg_id + 1) + callid_event.len + fromtag_event.len + pto->uri.len;
	memcpy(notify_cell->rem_uri.s, pfrom->uri.s, pfrom->uri.len);
	LM_DBG("SUBS_REM_URI: %.*s \n ", notify_cell->rem_uri.len, notify_cell->rem_uri.s );

	notify_cell->contact.len = vsp_addr_len + size_vsp_port +11;
	notify_cell->contact.s = (char *) (notify_cell->call_dlg_id + 1) +  pfrom->uri.len + pto->uri.len + callid_event.len + fromtag_event.len;

	memcpy(notify_cell->contact.s, "sip:teste@", 10);
	memcpy(notify_cell->contact.s + 10, vsp_addr, vsp_addr_len);
	memcpy(notify_cell->contact.s + 10 + vsp_addr_len, ":", 1);
	memcpy(notify_cell->contact.s + 11 + vsp_addr_len, str_vsp_port, size_vsp_port);
	LM_DBG("SUBS_CONTACT: %.*s \n ", notify_cell->contact.len, notify_cell->contact.s );

	notify_cell->dlg_id->status =  RESP_WAIT;

	pkg_free(callid_event.s);
	pkg_free(fromtag_event.s);

	return notify_cell;

}
Esempio n. 21
0
/*! \brief 
 * \return 0/1 (false/true) or -1 on error, -127 EXPR_DROP 
 */
static int eval_elem(struct expr* e, struct sip_msg* msg, pv_value_t *val)
{

	struct sip_uri uri;
	int ret;
	int retl;
	int retr;
	int ival;
	pv_value_t lval;
	pv_value_t rval;
	char *p;
	int i,n;
	
	ret=E_BUG;
	if (e->type!=ELEM_T){
		LM_CRIT("invalid type\n");
		goto error;
	}
	
	if(val) memset(val, 0, sizeof(pv_value_t));

	switch(e->left.type){
		case METHOD_O:
				ret=comp_strval(msg, e->op, &msg->first_line.u.request.method,
						&e->right);
				break;
		case URI_O:
				if(msg->new_uri.s){
					if (e->right.type==MYSELF_ST){
						if (parse_sip_msg_uri(msg)<0) ret=-1;
						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
									msg->parsed_uri.port_no?
									msg->parsed_uri.port_no:SIP_PORT);
					}else{
						ret=comp_strval(msg, e->op, &msg->new_uri, &e->right);
					}
				}else{
					if (e->right.type==MYSELF_ST){
						if (parse_sip_msg_uri(msg)<0) ret=-1;
						else	ret=check_self_op(e->op, &msg->parsed_uri.host,
									msg->parsed_uri.port_no?
									msg->parsed_uri.port_no:SIP_PORT);
					}else{
						ret=comp_strval(msg, e->op,
								&msg->first_line.u.request.uri,
								&e->right);
					}
				}
				break;
		case FROM_URI_O:
				if (parse_from_header(msg)<0){
					LM_ERR("bad or missing From: header\n");
					goto error;
				}
				if (e->right.type==MYSELF_ST){
					if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len,
									&uri) < 0){
						LM_ERR("bad uri in From:\n");
						goto error;
					}
					ret=check_self_op(e->op, &uri.host,
										uri.port_no?uri.port_no:SIP_PORT);
				}else{
					ret=comp_strval(msg, e->op, &get_from(msg)->uri,
							&e->right);
				}
				break;
		case TO_URI_O:
				if ((msg->to==0) && ((parse_headers(msg, HDR_TO_F, 0)==-1) ||
							(msg->to==0))){
					LM_ERR("bad or missing To: header\n");
					goto error;
				}
				/* to content is parsed automatically */
				if (e->right.type==MYSELF_ST){
					if (parse_uri(get_to(msg)->uri.s, get_to(msg)->uri.len,
									&uri) < 0){
						LM_ERR("bad uri in To:\n");
						goto error;
					}
					ret=check_self_op(e->op, &uri.host,
										uri.port_no?uri.port_no:SIP_PORT);
				}else{
					ret=comp_strval(msg, e->op, &get_to(msg)->uri,
										&e->right);
				}
				break;
		case SRCIP_O:
				ret=comp_ip(msg, e->op, &msg->rcv.src_ip, &e->right);
				break;
		case DSTIP_O:
				ret=comp_ip(msg, e->op, &msg->rcv.dst_ip, &e->right);
				break;
		case NUMBER_O:
				ret=!(!e->right.v.n); /* !! to transform it in {0,1} */
				break;
		case ACTION_O:
				ret=run_action_list( (struct action*)e->right.v.data, msg);
				if(val)
				{
					val->flags = PV_TYPE_INT|PV_VAL_INT;
					val->ri = ret;
				}
				if (ret<=0) ret=(ret==0)?EXPR_DROP:0;
				else ret=1;
				return ret;
		case EXPR_O:
				retl = retr = 0;
				memset(&lval, 0, sizeof(pv_value_t));
				memset(&rval, 0, sizeof(pv_value_t));
				if(e->left.v.data)
					retl=eval_expr((struct expr*)e->left.v.data,msg,&lval);
				if(lval.flags == PV_VAL_NONE)
				{
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 0;
				}
				if(e->op == BNOT_OP)
				{
					if(lval.flags&PV_VAL_INT)
					{
						if(val!=NULL)
						{
							val->flags = PV_TYPE_INT|PV_VAL_INT;
							val->ri = ~lval.ri;
						}
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return (val->ri)?1:0;
					}
					LM_ERR("binary NOT on non-numeric value\n");
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 0;
				}
				if(e->right.v.data)
					retr=eval_expr((struct expr*)e->right.v.data,msg,&rval);
			
				if(lval.flags&PV_TYPE_INT)
				{
					if( (rval.flags&PV_VAL_NULL) )
					{
						rval.ri = 0;
					} else if(!(rval.flags&PV_VAL_INT))
					{
						LM_ERR("invalid numeric operands\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					if(val!=NULL)
						val->flags = PV_TYPE_INT|PV_VAL_INT;

					ival = 0;
					switch(e->op) {
						case PLUS_OP:
							ival = lval.ri + rval.ri;
							break;
						case MINUS_OP:
							ival = lval.ri - rval.ri;
							break;
						case DIV_OP:
							if(rval.ri==0)
							{
								LM_ERR("divide by 0\n");
								pv_value_destroy(&lval);
								pv_value_destroy(&rval);
								return 0;
							} else 
								ival = lval.ri / rval.ri;
							break;
						case MULT_OP:
							ival = lval.ri * rval.ri;
							break;
						case MODULO_OP:
							if(rval.ri==0)
							{
								LM_ERR("divide by 0\n");
								pv_value_destroy(&lval);
								pv_value_destroy(&rval);
								return 0;
							} else 
								ival = lval.ri % rval.ri;
							break;
						case BAND_OP:
							ival = lval.ri & rval.ri;
							break;
						case BOR_OP:
							ival = lval.ri | rval.ri;
							break;
						case BXOR_OP:
							ival = lval.ri ^ rval.ri;
							break;
						case BLSHIFT_OP:
							ival = lval.ri << rval.ri;
							break;
						case BRSHIFT_OP:
							ival = lval.ri >> rval.ri;
							break;
						default:
							LM_ERR("invalid int op %d\n", e->op);
								val->ri = 0;
							pv_value_destroy(&lval);
							pv_value_destroy(&rval);
							return 0;
					}
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					if(val!=NULL) val->ri = ival;
					return (ival)?1:0;
				} else if (e->op == PLUS_OP) {
					if( (rval.flags&PV_VAL_NULL) || (val==NULL)) {
						if (val) val->flags|=PV_VAL_STR;
						ret = (lval.rs.len>0 || rval.rs.len>0);
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return ret;
					}
					if(!(rval.flags&PV_VAL_STR))
					{
						LM_ERR("invalid string operands\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					val->rs.s=(char*)pkg_malloc((lval.rs.len+rval.rs.len+1)
							*sizeof(char));
					if(val->rs.s==0)
					{
						LM_ERR("no more memory\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					val->flags = PV_VAL_PKG|PV_VAL_STR;
					memcpy(val->rs.s, lval.rs.s, lval.rs.len);
					memcpy(val->rs.s+lval.rs.len, rval.rs.s, rval.rs.len);
					val->rs.len = lval.rs.len + rval.rs.len;
					val->rs.s[val->rs.len] = '\0';
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 1;
				} else if ((lval.flags & PV_VAL_STR) && (rval.flags & PV_VAL_STR)) {
					if (lval.rs.len != rval.rs.len)
					{
						LM_ERR("Different length string operands\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					n = lval.rs.len;
					val->rs.s = pkg_malloc(n+1);
					if (!val->rs.s)
					{
						LM_ERR("no more memory\n");
						pv_value_destroy(&lval);
						pv_value_destroy(&rval);
						return 0;
					}
					switch(e->op) {
						case BAND_OP:
							for (i=0;i<n;i++)
								val->rs.s[i] = lval.rs.s[i] & rval.rs.s[i];
							break;
						case BOR_OP:
							for (i=0;i<n;i++)
								val->rs.s[i] = lval.rs.s[i] | rval.rs.s[i];
							break;
						case BXOR_OP:
							for (i=0;i<n;i++)
								val->rs.s[i] = lval.rs.s[i] ^ rval.rs.s[i];
							break;
						default:
							LM_ERR("Only bitwise operations can be applied on strings\n");
							val->ri = 0;
							pv_value_destroy(&lval);
							pv_value_destroy(&rval);
							return 0;
					}
					val->flags = PV_VAL_PKG|PV_VAL_STR;
					val->rs.len = n;
					val->rs.s[n] = '\0';
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 1;
				}
				else {
					LM_ERR("Invalid operator : %d \n",e->op);
					pv_value_destroy(&lval);
					pv_value_destroy(&rval);
					return 0;
				}
				break;
		case SRCPORT_O:
				ret=comp_no(msg->rcv.src_port, 
					e->right.v.data, /* e.g., 5060 */
					e->op, /* e.g. == */
					e->right.type /* 5060 is number */);
				break;
		case DSTPORT_O:
				ret=comp_no(msg->rcv.dst_port, e->right.v.data, e->op, 
							e->right.type);
				break;
		case PROTO_O:
				ret=comp_no(msg->rcv.proto, e->right.v.data, e->op,
						e->right.type);
				break;
		case AF_O:
				ret=comp_no(msg->rcv.src_ip.af, e->right.v.data, e->op,
						e->right.type);
				break;
		case RETCODE_O:
				ret=comp_no(return_code, e->right.v.data, e->op,
						e->right.type);
				break;
		case MSGLEN_O:
				ret=comp_no(msg->len, e->right.v.data, e->op,
						e->right.type);
				break;
		case STRINGV_O:
				if(val) {
					val->flags = PV_VAL_STR;
					val->rs = e->left.v.s;
				}
				/* optimization for no dup ?!?! */
				return (e->left.v.s.len>0)?1:0;
		case NUMBERV_O:
				if(val) {
					val->flags = PV_TYPE_INT|PV_VAL_INT;
					val->ri = e->left.v.n;
				}
				ret=!(!e->left.v.n); /* !! to transform it in {0,1} */
				return ret;
		case SCRIPTVAR_O:
				if(e->op==NO_OP)
				{
					memset(&rval, 0, sizeof(pv_value_t));
					if(pv_get_spec_value(msg, e->right.v.spec, &rval)==0)
					{
						if(rval.flags==PV_VAL_NONE || (rval.flags&PV_VAL_NULL)
								|| (rval.flags&PV_VAL_EMPTY)
								|| ((rval.flags&PV_TYPE_INT)&&rval.ri==0))
						{
							pv_value_destroy(&rval);
							return 0;
						}
						if(rval.flags&PV_TYPE_INT)
						{
							pv_value_destroy(&rval);
							return 1;
						}
						if(rval.rs.len!=0)
						{
							pv_value_destroy(&rval);
							return 1;
						}
						pv_value_destroy(&rval);
					}
					return 0;
				}
				if(e->op==VALUE_OP)
				{
					if(pv_get_spec_value(msg, e->left.v.spec, &lval)==0)
					{
						if(val!=NULL)
							memcpy(val, &lval, sizeof(pv_value_t));
						if(lval.flags&PV_VAL_STR)
						{
							if(!((lval.flags&PV_VAL_PKG) 
									|| (lval.flags&PV_VAL_SHM)))
							{
								if(val!=NULL)
								{
									/* do pkg duplicate */
									p = (char*)pkg_malloc((val->rs.len+1)
											*sizeof(char));
									if(p==0)
									{
										LM_ERR("no more pkg memory\n");
										memset(val, 0, sizeof(pv_value_t));
										return 0;
									}
									memcpy(p, val->rs.s, val->rs.len);
									p[val->rs.len] = 0;
									val->rs.s = p;
									val->flags|= PV_VAL_PKG;
								}
							}
							return 1;
						}
						if(lval.flags==PV_VAL_NONE 
								|| (lval.flags & PV_VAL_NULL)
								|| (lval.flags & PV_VAL_EMPTY))
							return 0;
						if(lval.flags&PV_TYPE_INT)
							return (lval.ri!=0);
						else
							return (lval.rs.len>0);
					}
					return 0;
				}

				ret=comp_scriptvar(msg, e->op, &e->left, &e->right);
				break;
		default:
				LM_CRIT("invalid operand %d\n", e->left.type);
	}
Esempio n. 22
0
int tps_request_received(sip_msg_t *msg, int dialog)
{
	tps_data_t mtsd;
	tps_data_t stsd;
	str lkey;
	str ftag;
	str nuri;
	uint32_t direction = TPS_DIR_DOWNSTREAM;
	int ret;

	LM_DBG("handling incoming request\n");

	if(dialog==0) {
		/* nothing to do for initial request */
		return 0;
	}

	memset(&mtsd, 0, sizeof(tps_data_t));
	memset(&stsd, 0, sizeof(tps_data_t));

	if(tps_pack_message(msg, &mtsd)<0) {
		LM_ERR("failed to extract and pack the headers\n");
		return -1;
	}

	ret = tps_dlg_message_update(msg, &mtsd);
	if(ret<0) {
		LM_ERR("failed to update on dlg message\n");
		return -1;
	}

	lkey = msg->callid->body;

	tps_storage_lock_get(&lkey);

	if(tps_storage_load_dialog(msg, &mtsd, &stsd)<0) {
		goto error;
	}

	/* detect direction - get from-tag */
	if(parse_from_header(msg)<0 || msg->from==NULL) {
		LM_ERR("failed getting 'from' header!\n");
		goto error;
	}
	ftag = get_from(msg)->tag_value;

	if(stsd.a_tag.len!=ftag.len) {
		direction = TPS_DIR_UPSTREAM;
	} else {
		if(memcmp(stsd.a_tag.s, ftag.s, ftag.len)==0) {
			direction = TPS_DIR_DOWNSTREAM;
		} else {
			direction = TPS_DIR_UPSTREAM;
		}
	}
	mtsd.direction = direction;

	tps_storage_lock_release(&lkey);

	if(direction == TPS_DIR_UPSTREAM) {
		nuri = stsd.a_contact;
	} else {
		nuri = stsd.b_contact;
	}
	if(nuri.len>0) {
		if(rewrite_uri(msg, &nuri)<0) {
			LM_ERR("failed to update r-uri\n");
			return -1;
		}
	}

	if(tps_reappend_route(msg, &stsd, &stsd.s_rr,
				(direction==TPS_DIR_UPSTREAM)?0:1)<0) {
		LM_ERR("failed to reappend s-route\n");
		return -1;
	}
	if(direction == TPS_DIR_UPSTREAM) {
		if(tps_reappend_route(msg, &stsd, &stsd.a_rr, 0)<0) {
			LM_ERR("failed to reappend a-route\n");
			return -1;
		}
	} else {
		if(tps_reappend_route(msg, &stsd, &stsd.b_rr, 0)<0) {
			LM_ERR("failed to reappend b-route\n");
			return -1;
		}
	}
	if(dialog!=0) {
		tps_append_xuuid(msg, &stsd.a_uuid);
	}
	return 0;

error:
	tps_storage_lock_release(&lkey);
	return -1;
}
Esempio n. 23
0
static int cmd_send_message(struct sip_msg* msg, char* _foo, char* _bar)
{
	str body, from_uri, dst, tagid;
	int mime;

	LM_DBG("cmd_send_message\n");

	/* extract body */
	if (get_body(msg,&body)!=0 || body.len==0) {
		LM_ERR("failed to extract body\n");
		return -1;
	}
	if ((mime = parse_content_type_hdr(msg)) < 1) {
		LM_ERR("failed parse content-type\n");
		return -1;
	}
	if (mime != (TYPE_TEXT << 16) + SUBTYPE_PLAIN
			&& mime != (TYPE_MESSAGE << 16) + SUBTYPE_CPIM) {
		LM_ERR("invalid content-type 0x%x\n", mime);
		return -1;
	}

	/* extract sender */
	if (parse_headers(msg, HDR_TO_F | HDR_FROM_F, 0) == -1 || !msg->to
			|| !msg->from) {
		LM_ERR("no To/From headers\n");
		return -1;
	}
	if (parse_from_header(msg) < 0 || !msg->from->parsed) {
		LM_ERR("failed to parse From header\n");
		return -1;
	}

	from_uri.s = uri_sip2xmpp(&((struct to_body *) msg->from->parsed)->uri);
	from_uri.len = strlen(from_uri.s);

	tagid = ((struct to_body *) msg->from->parsed)->tag_value;
	LM_DBG("message from <%.*s>\n", from_uri.len, from_uri.s);

	/* extract recipient */
	dst.len = 0;
	if (msg->new_uri.len > 0) {
		LM_DBG("using new URI as destination\n");
		dst = msg->new_uri;
	} else if (msg->first_line.u.request.uri.s
			&& msg->first_line.u.request.uri.len > 0) {
		LM_DBG("using R-URI as destination\n");
		dst = msg->first_line.u.request.uri;
	} else if (msg->to->parsed) {
		LM_DBG("using TO-URI as destination\n");
		dst = ((struct to_body *) msg->to->parsed)->uri;
	} else {
		LM_ERR("failed to find a valid destination\n");
		return -1;
	}
	dst.s = dst.s + 4;
	dst.len = dst.len - 4;

	if (!xmpp_send_pipe_cmd(XMPP_PIPE_SEND_MESSAGE, &from_uri, &dst, &body,
				&tagid))
		return 1;
	return -1;
}
Esempio n. 24
0
int tps_response_received(sip_msg_t *msg)
{
	tps_data_t mtsd;
	tps_data_t stsd;
	tps_data_t btsd;
	str lkey;
	str ftag;
	uint32_t direction;

	LM_DBG("handling incoming response\n");

	if(msg->first_line.u.reply.statuscode==100) {
		/* nothing to do - it should be absorbed */
		return 0;
	}

	memset(&mtsd, 0, sizeof(tps_data_t));
	memset(&stsd, 0, sizeof(tps_data_t));
	memset(&btsd, 0, sizeof(tps_data_t));

	lkey = msg->callid->body;

	if(tps_pack_message(msg, &mtsd)<0) {
		LM_ERR("failed to extract and pack the headers\n");
		return -1;
	}
	tps_storage_lock_get(&lkey);
	if(tps_storage_load_branch(msg, &mtsd, &btsd)<0) {
		goto error;
	}
	LM_DBG("loaded dialog a_uuid [%.*s]\n",
			btsd.a_uuid.len, ZSW(btsd.a_uuid.s));
	if(tps_storage_load_dialog(msg, &btsd, &stsd)<0) {
		goto error;
	}

	/* detect direction - get from-tag */
	if(parse_from_header(msg)<0 || msg->from==NULL) {
		LM_ERR("failed getting 'from' header!\n");
		goto error;
	}
	ftag = get_from(msg)->tag_value;

	if(stsd.a_tag.len!=ftag.len) {
		direction = TPS_DIR_UPSTREAM;
	} else {
		if(memcmp(stsd.a_tag.s, ftag.s, ftag.len)==0) {
			direction = TPS_DIR_DOWNSTREAM;
		} else {
			direction = TPS_DIR_UPSTREAM;
		}
	}
	mtsd.direction = direction;
	if(tps_storage_update_branch(msg, &mtsd, &btsd)<0) {
		goto error;
	}
	if(tps_storage_update_dialog(msg, &mtsd, &stsd)<0) {
		goto error;
	}
	tps_storage_lock_release(&lkey);

	tps_reappend_via(msg, &btsd, &btsd.x_via);
	tps_reappend_rr(msg, &btsd, &btsd.s_rr);
	tps_reappend_rr(msg, &btsd, &btsd.x_rr);
	tps_append_xbranch(msg, &mtsd.x_vbranch1);

	return 0;

error:
	tps_storage_lock_release(&lkey);
	return -1;
}
Esempio n. 25
0
/*! \brief
 * Insert a new Record-Route header field
 * And also 2nd one if it is enabled and realm changed so
 * the 2nd record-route header will be necessary
 */
int record_route(struct sip_msg* _m, str *params)
{
	struct lump* l, *l2, *lp, *lp2, *ap;
	str user;
	struct to_body* from;
	str* tag;

	from = 0; /* Makes gcc happy */
	user.len = 0;
	lp = lp2 = NULL;

	if (add_username) {
		if (get_username(_m, &user) < 0) {
			LM_ERR("failed to extract username\n");
			return -1;
		}
	}

	if (append_fromtag) {
		if (parse_from_header(_m) < 0) {
			LM_ERR("From parsing failed\n");
			return -2;
		}
		from = (struct to_body*)_m->from->parsed;
		tag = &from->tag_value;
	} else {
		tag = 0;
	}

	l = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	if (!l || !l2) {
		LM_ERR("failed to create an anchor\n");
		return -3;
	}

	/* look for pending RR params */
	for( lp2=NULL,lp=NULL,ap=_m->add_rm ; ap ; ap=ap->next ) {
		if (ap->type==HDR_RECORDROUTE_T && ap->op==LUMP_NOP
		&& ap->before && ap->before->op==LUMP_ADD_OPT
		&& ap->before->u.cond==COND_FALSE) {
			/* found our phony anchor lump */
			/* jump over the anchor and conditional lumps */
			lp = ap->before->before;
			/* unlink it */
			ap->before->before = NULL;
			ap->type = 0;
			/* if double routing, make a copy of the buffered lumps for the
			   second route hdr. */
			if (enable_double_rr)
				lp2 = dup_lump_list(lp);
			break;
		}
	}

	if (build_rr(l, l2, &user, tag, params, lp, OUTBOUND) < 0) {
		LM_ERR("failed to insert inbound Record-Route\n");
		return -4;
	}

	if (enable_double_rr) {
		l = anchor_lump(_m, _m->headers->name.s - _m->buf,HDR_RECORDROUTE_T);
		l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
		if (!l || !l2) {
			LM_ERR("failed to create an anchor\n");
			return -5;
		}
		l = insert_cond_lump_after(l, COND_IF_DIFF_REALMS, 0);
		l2 = insert_cond_lump_before(l2, COND_IF_DIFF_REALMS, 0);
		if (!l || !l2) {
			LM_ERR("failed to insert conditional lump\n");
			return -6;
		}
		if (build_rr(l, l2, &user, tag, params, lp2, INBOUND) < 0) {
			LM_ERR("failed to insert outbound Record-Route\n");
			return -7;
		}
	}

	return 0;
}
Esempio n. 26
0
int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2)
{
	publ_info_t publ;
	struct to_body *pto= NULL, TO, *pfrom = NULL;
	str body;
	ua_pres_t dialog;
	unsigned int expires= 0;
	struct hdr_field* hdr;
	str subs_state;
	str extra_headers= {0, 0};
	static char buf[255];
	str contact;

	memset(&publ, 0, sizeof(publ_info_t));
	memset(&dialog, 0, sizeof(ua_pres_t));

	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}
	/* examine the to header */
	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
				pto->uri.len, pto->uri.s );
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0)
		{
			LM_DBG("'To' header NOT parsed\n");
			return -1;
		}
		pto = &TO;
	}
	publ.pres_uri= &pto->uri;
	dialog.watcher_uri= publ.pres_uri;

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("NULL to_tag value\n");
		return -1;
	}
	dialog.from_tag= pto->tag_value;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		return -1;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		return -1;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG(" 'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_DBG(" ERROR cannot parse From header\n");
			return -1;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.to_uri= pfrom->uri;

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		return -1;
	}
	if ( get_content_length(msg) == 0 )
	{
		LM_DBG("content length= 0\n");
		return 1;
	}
	else
	{
		body.s=get_body(msg);
		if (body.s== NULL)
		{
			LM_ERR("cannot extract body from msg\n");
			return -1;
		}
		body.len = get_content_length( msg );

		if (!bla_body_is_valid( &body ))
		{
			LM_ERR("bad XML body!");
			return -1;
		}
	}
   	
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		return -1;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		return -1;
	}

	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		return -1;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	dialog.to_tag= pfrom->tag_value;
	dialog.event= BLA_EVENT;
	dialog.flag= BLA_SUBSCRIBE;
	if(pua_is_dialog(&dialog)< 0)
	{
		LM_ERR("Notify in a non existing dialog\n");
		return -2;
	}

	/* parse Subscription-State and extract expires if existing */
	hdr = get_header_by_static_name( msg, "Subscription-State");
	if( hdr==NULL )
	{
		LM_ERR("No Subscription-State header found\n");
		return -1;
	}
	subs_state= hdr->body;
	if(strncasecmp(subs_state.s, "terminated", 10)== 0)
		expires= 0;
	else
	{
		if(strncasecmp(subs_state.s, "active", 6)== 0 ||
				strncasecmp(subs_state.s, "pending", 7)==0 )
		{
			expires = DEFAULT_EXPIRES;
			char* sep= NULL;
			str exp= {NULL, 0};
			sep= strchr(subs_state.s, ';');
			if(sep)
			{
				if(strncasecmp(sep+1, "expires=", 8)== 0)
				{
					exp.s= sep+ 9;
					sep= exp.s;
					while((*sep)>='0' && (*sep)<='9')
					{
						sep++;
						exp.len++;
					}
					if( str2int(&exp, &expires)< 0)
					{
						LM_ERR("while parsing int\n");
						return -1;
					}
				}
			}
		}
		else
		{
			LM_ERR("unknown Subscription-state token\n");
			return -1;
		}
	}

	/* +2 for ": " between header name and value */
	if ((header_name.len + 2 + contact.len + CRLF_LEN) >= sizeof(buf)) {
		LM_ERR("Sender header too large");
		return -1;
	}

	/* build extra_headers with Sender*/
	extra_headers.s= buf;
	memcpy(extra_headers.s, header_name.s, header_name.len);
	extra_headers.len= header_name.len;
	memcpy(extra_headers.s+extra_headers.len,": ",2);
	extra_headers.len+= 2;
	memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len);
	extra_headers.len+= contact.len;
	memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN);
	extra_headers.len+= CRLF_LEN;

	publ.id= contact;
	publ.body= &body;
	publ.source_flag= BLA_PUBLISH;
	publ.expires= expires;
	publ.event= BLA_EVENT;
	publ.extra_headers= &extra_headers;
	publ.outbound_proxy = presence_server;

	if(pua_send_publish(&publ)< 0)
	{
		LM_ERR("failed to send Publish message\n");
		return -1;
	}

	return 1;
}
Esempio n. 27
0
/* builds digest string of msg
   Return value: 1: success
                 0: else
    digestString must point to an array with at least MAX_DIGEST bytes
*/
static int makeDigestString(char * digestString, char * dateHF,
														struct sip_msg * msg)
{
	struct to_body * from = NULL;
	struct to_body * to = NULL;
	struct cseq_body * cseq = NULL;
	struct hdr_field * date = NULL;
	contact_t * contact = NULL;
	unsigned int l;
	str tmp;

	if(!digestString || !msg)
	{
		LM_ERR("not all parameters set\n");
		return 0;
	}

	l = 0;

	/* ###from### */
	if(parse_from_header(msg) != 0)
	{
		LM_ERR("error parsing from header\n");
		return 0;
	}

	from = get_from(msg);
	if(!from)
	{
		LM_ERR("error getting from header\n");
		return 0;
	}

	if (l+from->uri.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 1\n");
		return 0;
	}
	memcpy( digestString+l, from->uri.s, from->uri.len);
	l += from->uri.len;
	*(digestString+(l++)) = '|';

	/* ###To### */
	to = get_to(msg);
	if(!to)
	{
		LM_ERR("error getting to header\n");
		return 0;
	}

	if (l+to->uri.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 2\n");
		return 0;
	}
	memcpy( digestString+l, to->uri.s, to->uri.len);
	l += to->uri.len;
	*(digestString+(l++)) = '|';

	/* ###callid### */
	if(!msg->callid)
	{
		LM_ERR("error getting callid header\n");
		return 0;
	}

	if (l+msg->callid->body.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 3\n");
		return 0;
	}
	memcpy( digestString+l, msg->callid->body.s, msg->callid->body.len);
	l += msg->callid->body.len;
	*(digestString+(l++)) = '|';

	/* ###CSeq### */
	cseq = (struct cseq_body *)msg->cseq->parsed;
	if (!cseq)
	{
		LM_ERR("error getting cseq header\n");
		return 0;
	}

	tmp.s = cseq->number.s;
	tmp.len = cseq->number.len;

	/* strip leading zeros */
	while((*(tmp.s) == '0') && (tmp.len > 1))
	{
		(tmp.s)++;
		(tmp.len)--;
	}

	if (l+tmp.len+cseq->method.len+2>MAX_DIGEST) {
		LM_ERR("buffer to short 4\n");
		return 0;
	}
	memcpy( digestString+l, tmp.s, tmp.len);
	l += tmp.len;
	*(digestString+(l++)) = ' ';
	memcpy( digestString+l, cseq->method.s, cseq->method.len);
	l += cseq->method.len;
	*(digestString+(l++)) = '|';

	/* ###Date### */
	if(!dateHF)
	{
		/* Date header field is taken from msg: verifier */
		date = get_header_by_static_name(msg,"Date");
		if (!date)
		{
			LM_ERR("error getting date header\n");
			return 0;
		}
		tmp = date->body;
	}
	else
	{
		/* Date header field is taken from dateHF: authentication service */
		tmp.s = dateHF;
		tmp.len = strlen(tmp.s);
	}

	if (l+tmp.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 5\n");
		return 0;
	}
	memcpy( digestString+l, tmp.s, tmp.len);
	l += tmp.len;
	*(digestString+(l++)) = '|';

	/* ###Contact### */
	if(msg->contact)
	{
		if(parse_contact(msg->contact) != 0)
		{
			LM_ERR("error parsing contact header\n");
			return 0;
		}
		/* first contact in list */
		contact = ((contact_body_t *)(msg->contact->parsed))->contacts;
		tmp = contact->uri;
	} else {
		tmp.len = 0;
		tmp.s = 0;
	}

	if (l+tmp.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 6\n");
		return 0;
	}
	if (tmp.len) {
		memcpy( digestString+l, tmp.s, tmp.len);
		l += tmp.len;
	}
	*(digestString+(l++)) = '|';

	/* ###body### */
	if ( get_body(msg,&tmp)!=0 ) {
		LM_ERR("failed to inspect body\n");
		return 0;
	}
	if (tmp.len != 0) {
		if (l+tmp.len+1>MAX_DIGEST) {
			LM_ERR("buffer to short 7\n");
			return 0;
		}
		memcpy( digestString+l, tmp.s, tmp.len);
		l += tmp.len;
		*(digestString+(l++)) = 0;
	}

	LM_DBG("Digest-String=>%s<\n", digestString);
	return 1;
}
Esempio n. 28
0
int push_on_network(struct sip_msg *msg, int net)
{
	str    body;
	struct sip_uri  uri;
	struct sms_msg  *sms_messg;
	struct to_body  *from;
	char   *p;
	int    len;
	int    mime;

	/* get the message's body
	 * anyhow we have to call this function, so let's do it at the beginning
	 * to force the parsing of all the headers - like this we avoid separate
	 * calls of parse_headers function for FROM, CONTENT_LENGTH, TO hdrs  */
	body.s = get_body( msg );
	if (body.s==0) {
		LM_ERR("failed to extract body from msg!\n");
		goto error;
	}

	/* content-length (if present) must be already parsed */
	if (!msg->content_length) {
		LM_ERR("no Content-Length header found!\n");
		goto error;
	}
	body.len = get_content_length( msg );

	/* parse the content-type header */
	if ( (mime=parse_content_type_hdr(msg))<1 ) {
		LM_ERR("failed to parse Content-Type header\n");
		goto error;
	}

	/* check the content-type value */
	if ( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
	&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM ) {
		LM_ERR("invalid content-type for a message request! type found=%d\n",
				mime);
		goto error;
	}

	/* we try to get the user name (phone number) first from the RURI 
	   (in our case means from new_uri or from first_line.u.request.uri);
	   if it's missing there (like in requests generated by MSN MESSENGER),
	   we go for "to" header
	*/
	LM_DBG("string to get user from new_uri\n");
	if ( !msg->new_uri.s||parse_uri( msg->new_uri.s,msg->new_uri.len,&uri)
	|| !uri.user.len )
	{
		LM_DBG("string to get user from R_uri\n");
		if ( parse_uri( msg->first_line.u.request.uri.s,
		msg->first_line.u.request.uri.len ,&uri)||!uri.user.len )
		{
			LM_DBG("string to get user from To\n");
			if ( (!msg->to&&((parse_headers(msg,HDR_TO_F,0)==-1) ||
					!msg->to)) ||
				parse_uri( get_to(msg)->uri.s, get_to(msg)->uri.len, &uri)==-1
			|| !uri.user.len)
			{
				LM_ERR("unable to extract user name from RURI and To header!\n");
				goto error;
			}
		}
	}
	/* check the uri.user format = '+(inter code)(number)' */
	if (uri.user.len<2 || uri.user.s[0]!='+' || uri.user.s[1]<'1'
	|| uri.user.s[1]>'9') {
		LM_ERR("user tel number [%.*s] does not respect international format\n"
				,uri.user.len,uri.user.s);
		goto error;
	}

	/* parsing from header */
	if ( parse_from_header( msg )==-1 ) {
		LM_ERR("failed to get FROM header\n");
		goto error;
	}
	from = (struct to_body*)msg->from->parsed;

#if 0
	/* adds contact header into reply */
	if (add_contact(msg,&(uri.user))==-1) {
		LM_ERR("can't build contact for reply\n");
		goto error;
	}
#endif

	/*-------------BUILD AND FILL THE SMS_MSG STRUCTURE --------------------*/
	/* computes the amount of memory needed */
	len = SMS_HDR_BF_ADDR_LEN + from->uri.len
		+ SMS_HDR_AF_ADDR_LEN + body.len + SMS_FOOTER_LEN /*text to send*/
		+ from->uri.len /* from */
		+ uri.user.len-1 /* to user (without '+') */
		+ sizeof(struct sms_msg) ; /* the sms_msg structure */
	/* allocs a new sms_msg structure in shared memory */
	sms_messg = (struct sms_msg*)shm_malloc(len);
	if (!sms_messg) {
		LM_ERR("failed to get shm memory!\n");
		goto error;
	}
	p = (char*)sms_messg + sizeof(struct sms_msg);

	/* copy "from" into sms struct */
	sms_messg->from.len = from->uri.len;
	sms_messg->from.s = p;
	append_str(p,from->uri.s,from->uri.len);

	/* copy "to.user" - we have to strip out the '+' */
	sms_messg->to.len = uri.user.len-1;
	sms_messg->to.s = p;
	append_str(p,uri.user.s+1,sms_messg->to.len);

	/* copy (and composing) sms body */
	sms_messg->text.len = SMS_HDR_BF_ADDR_LEN + sms_messg->from.len
		+ SMS_HDR_AF_ADDR_LEN + body.len+SMS_FOOTER_LEN;
	sms_messg->text.s = p;
	append_str(p, SMS_HDR_BF_ADDR, SMS_HDR_BF_ADDR_LEN);
	append_str(p, sms_messg->from.s, sms_messg->from.len);
	append_str(p, SMS_HDR_AF_ADDR, SMS_HDR_AF_ADDR_LEN);
	append_str(p, body.s, body.len);
	append_str(p, SMS_FOOTER, SMS_FOOTER_LEN);

	if (*queued_msgs>MAX_QUEUED_MESSAGES)
		goto error;
	(*queued_msgs)++;

	if (write(net_pipes_in[net], &sms_messg, sizeof(sms_messg))!=
	sizeof(sms_messg) )
	{
		LM_ERR("error when writing for net %d to pipe [%d] : %s\n",
				net,net_pipes_in[net],strerror(errno) );
		shm_free(sms_messg);
		(*queued_msgs)--;
		goto error;
	}

	return 1;
 error:
	return -1;
}
Esempio n. 29
0
/*
 * Check if an entry exists in hash table that has given src_ip and protocol
 * value and pattern that matches to From URI.  If an entry exists and tag_avp
 * has been defined, tag of the entry is added as a value to tag_avp.
 * Returns number of matches or -1 if none matched.
 */
int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
		char *src_ip_c_str, int proto)
{
	str uri, ruri;
	char uri_string[MAX_URI_SIZE + 1];
	char ruri_string[MAX_URI_SIZE + 1];
	regex_t preg;
	struct trusted_list *np;
	str src_ip;
	int_str val;
	int count = 0;

	src_ip.s = src_ip_c_str;
	src_ip.len = strlen(src_ip.s);

	if (IS_SIP(msg))
	{
		if (parse_from_header(msg) < 0) return -1;
		uri = get_from(msg)->uri;
		if (uri.len > MAX_URI_SIZE) {
			LM_ERR("from URI too large\n");
			return -1;
		}
		memcpy(uri_string, uri.s, uri.len);
		uri_string[uri.len] = (char)0;
		ruri = msg->first_line.u.request.uri;
		if (ruri.len > MAX_URI_SIZE) {
			LM_ERR("message has Request URI too large\n");
			return -1;
		}
		memcpy(ruri_string, ruri.s, ruri.len);
		ruri_string[ruri.len] = (char)0;
	}

	for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) {
		if ((np->src_ip.len == src_ip.len) &&
				(strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) &&
				((np->proto == PROTO_NONE) || (proto == PROTO_NONE) ||
				(np->proto == proto))) {
			if (IS_SIP(msg)) {
				if (np->pattern) {
					if (regcomp(&preg, np->pattern, REG_NOSUB)) {
						LM_ERR("invalid regular expression\n");
						if (!np->ruri_pattern) {
							continue;
						}
					}
					if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
						regfree(&preg);
						continue;
					}
					regfree(&preg);
				}
				if (np->ruri_pattern) {
					if (regcomp(&preg, np->ruri_pattern, REG_NOSUB)) {
						LM_ERR("invalid regular expression\n");
						continue;
					}
					if (regexec(&preg, ruri_string, 0, (regmatch_t *)0, 0)) {
						regfree(&preg);
						continue;
					}
					regfree(&preg);
				}
			}
			/* Found a match */
			if (tag_avp.n && np->tag.s) {
				val.s = np->tag;
				if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) {
					LM_ERR("setting of tag_avp failed\n");
					return -1;
				}
			}
			if (!peer_tag_mode)
				return 1;
			count++;
		}
	}
	if (!count)
		return -1;
	else
		return count;
}
Esempio n. 30
0
/*
 * Check if from user is a valid enum based user, and check to make sure
 * that the src_ip == an srv record that maps to the enum from user.
 */
int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service)
{
	struct ip_addr addr;
	struct hostent* he;
	unsigned short zp;
	char proto;
	char *user_s;
	int user_len, i, j;
	char name[MAX_DOMAIN_SIZE];
	char uri[MAX_URI_SIZE];
	struct sip_uri *furi;
	struct sip_uri luri;
	struct rdata* head;

	str* suffix;
	str* service;

	struct rdata* l;
	struct naptr_rdata* naptr;

	str pattern, replacement, result;
	char string[MAX_NUM_LEN];

	if (parse_from_header(_msg) < 0) {
	    LM_ERR("Failed to parse From header\n");
	    return -1;
	}
	
	if(_msg->from==NULL || get_from(_msg)==NULL) {
	    LM_DBG("No From header\n");
	    return -1;
	}

	if ((furi = parse_from_uri(_msg)) == NULL) {
	    LM_ERR("Failed to parse From URI\n");
	    return -1;
	}

	suffix = (str*)_suffix;
	service = (str*)_service;

	if (is_e164(&(furi->user)) == -1) {
	    LM_ERR("From URI user is not an E164 number\n");
	    return -1;
	}

	/* assert: the from user is a valid formatted e164 string */

	user_s = furi->user.s;
	user_len = furi->user.len;

	j = 0;
	for (i = user_len - 1; i > 0; i--) {
		name[j] = user_s[i];
		name[j + 1] = '.';
		j = j + 2;
	}

	memcpy(name + j, suffix->s, suffix->len + 1);

	head = get_record(name, T_NAPTR, RES_ONLY_TYPE);

	if (head == 0) {
		LM_DBG("No NAPTR record found for %s.\n", name);
		return -3;
	}

	/* we have the naptr records, loop and find an srv record with */
	/* same ip address as source ip address, if we do then true is returned */

	for (l = head; l; l = l->next) {

		if (l->type != T_NAPTR) continue; /*should never happen*/
		naptr = (struct naptr_rdata*)l->rdata;
		if (naptr == 0) {
			LM_ERR("Null rdata in DNS response\n");
			free_rdata_list(head);
			return -4;
		}

		LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
		       "'%.*s', slen %u, services '%.*s', rlen %u, "
		       "regexp '%.*s'\n",
		       name, naptr->order, naptr->pref,
		    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len,
		    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
		    (int)(naptr->regexp_len), ZSW(naptr->regexp));

		if (sip_match(naptr, service) != 0) {
			if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
					 &pattern, &replacement) < 0) {
				free_rdata_list(head); /*clean up*/
				LM_ERR("Parsing of NAPTR regexp failed\n");
				return -5;
			}
#ifdef LATER
			if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) {
				LM_DBG("Resulted in replacement: '%.*s'\n",
				       replacement.len, ZSW(replacement.s));				
				retval = set_uri(_msg, replacement.s, replacement.len);
				free_rdata_list(head); /*clean up*/
				return retval;
			}
#endif
			result.s = &(uri[0]);
			result.len = MAX_URI_SIZE;
			/* Avoid making copies of pattern and replacement */
			pattern.s[pattern.len] = (char)0;
			replacement.s[replacement.len] = (char)0;
			/* We have already checked the size of
			   _msg->parsed_uri.user.s */ 
			memcpy(&(string[0]), user_s, user_len);
			string[user_len] = (char)0;
			if (reg_replace(pattern.s, replacement.s, &(string[0]),
					&result) < 0) {
				pattern.s[pattern.len] = '!';
				replacement.s[replacement.len] = '!';
				LM_ERR("Regexp replace failed\n");
				free_rdata_list(head); /*clean up*/
				return -6;
			}
			LM_DBG("Resulted in replacement: '%.*s'\n",
			    result.len, ZSW(result.s));

			if(parse_uri(result.s, result.len, &luri) < 0)
			{
				LM_ERR("Parsing of URI <%.*s> failed\n",
				       result.len, result.s);
				free_rdata_list(head); /*clean up*/
				return -7;
			}

			pattern.s[pattern.len] = '!';
			replacement.s[replacement.len] = '!';

			zp = 0;
			proto = PROTO_NONE;
			he = sip_resolvehost(&luri.host, &zp, &proto);

			hostent2ip_addr(&addr, he, 0);

			if(ip_addr_cmp(&addr, &_msg->rcv.src_ip))
			{
				free_rdata_list(head);
				return(1);
			}
		}
	}
	free_rdata_list(head); /*clean up*/
	LM_DBG("FAIL\n");

    /* must not have found the record */
    return(-8);
}