Esempio n. 1
0
/*
 * Insert a row into table
 */
int dbt_insert(db1_con_t* _h, db_key_t* _k, db_val_t* _v, int _n)
{
	dbt_table_p _tbc = NULL;
	dbt_row_p _drp = NULL;
	
	int *lkey=NULL, i, j;
	
	if (!_h || !CON_TABLE(_h))
	{
		LM_ERR("invalid parameter\n");
		return -1;
	}
	if(!_k || !_v || _n<=0)
	{
		LM_ERR("no key-value to insert\n");
		return -1;
	}
	
	/* lock database */
	_tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(!_tbc)
	{
		LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
		return -1;
	}

	if(_tbc->nrcols<_n)
	{
		LM_ERR("more values than columns!!\n");
		goto error;
	}
	
	if(_k)
	{
		lkey = dbt_get_refs(_tbc, _k, _n);
		if(!lkey)
			goto error;
	}
	_drp = dbt_row_new(_tbc->nrcols);
	if(!_drp)
	{
		LM_ERR("no shm memory for a new row!!\n");
		goto error;
	}
	
	for(i=0; i<_n; i++)
	{
		j = (lkey)?lkey[i]:i;
		if(dbt_is_neq_type(_tbc->colv[j]->type, _v[i].type))
		{
			LM_ERR("incompatible types v[%d] - c[%d]!\n", i, j);
			goto clean;
		}
		if(_v[i].type == DB1_STRING && !_v[i].nul)
			_v[i].val.str_val.len = strlen(_v[i].val.string_val);
		if(dbt_row_set_val(_drp, &(_v[i]), _tbc->colv[j]->type, j))
		{
			LM_ERR("cannot set v[%d] in c[%d]!\n", i, j);
			goto clean;
		}
		
	}

	if(dbt_table_add_row(_tbc, _drp))
	{
		LM_ERR("cannot insert the new row!!\n");
		goto clean;
	}

	/* dbt_print_table(_tbc, NULL); */
	
	/* unlock databse */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

	if(lkey)
		pkg_free(lkey);

    return 0;
	
error:
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(lkey)
		pkg_free(lkey);
	LM_ERR("failed to insert row in table!\n");
    return -1;
	
clean:
	if(lkey)
		pkg_free(lkey);
	
	if(_drp) // free row
		dbt_row_free(_tbc, _drp);
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	
    return -1;
}
Esempio n. 2
0
int pres_watcher_allowed(subs_t* subs)
{
	xmlDocPtr xcap_tree = NULL;
        xmlNodePtr node = NULL, actions_node = NULL, sub_handling_node = NULL;
	char* sub_handling = NULL;
	int action_value = -1, ret = 0;
	str watcher = {0, 0};

	uandd_to_uri(subs->from_user, subs->from_domain, &watcher);
	if(watcher.s == NULL)
	{
		LM_ERR("while creating uri\n");
		return -1;
	}

	/* if force_active set status to active*/
	if(force_active)
	{
		subs->status = ACTIVE_STATUS;
		subs->reason.s = NULL;
		subs->reason.len = 0;
		ret = 0;
		goto done;
	}

	if(subs->auth_rules_doc == NULL)
	{
		subs->status = PENDING_STATUS;
		subs->reason.s = NULL;
		subs->reason.len = 0;
		ret = 0;
		goto done;
	}

	xcap_tree = xmlParseMemory(subs->auth_rules_doc->s, subs->auth_rules_doc->len);
	if(xcap_tree == NULL)
	{
		LM_ERR("parsing xml memory\n");
		ret = -1;
		goto done;
	}

	node = get_rule_node(subs, xcap_tree);
	if(node == NULL)
	{
		/* if no rule node was found and the previous state was active -> set the
		 * state to terminated with reason deactivated */
		if(subs->status != PENDING_STATUS)
		{
			subs->status = TERMINATED_STATUS;
			subs->reason.s = "deactivated";
			subs->reason.len = 11;
		}
		ret = 0;
		goto done;
	}

        /* If node is not NULL then there should be a actions element and a sub-handling element
         * for sure, get_rule_node makes sure of that */

        actions_node = xmlNodeGetChildByName(node, "actions");
        if (actions_node == NULL)
        {
                ret = -1;
                goto done;
        }
        sub_handling_node = xmlNodeGetChildByName(actions_node, "sub-handling");
        if (sub_handling_node == NULL)
        {
                ret = -1;
                goto done;
        }
        sub_handling = (char*)xmlNodeGetContent(sub_handling_node);
        if (sub_handling == NULL)
        {
                ret = -1;
                goto done;
        }

        action_value = get_action_value(sub_handling);
        switch (action_value)
        {
                case SH_ACTION_BLOCK:
                        subs->status = TERMINATED_STATUS;
                        subs->reason.s = "rejected";
                        subs->reason.len = 8;
                        break;
                case SH_ACTION_CONFIRM:
                        subs->status = PENDING_STATUS;
                        subs->reason.s = NULL;
                        subs->reason.len = 0;
                        break;
                case SH_ACTION_POLITE_BLOCK:
                        subs->status = ACTIVE_STATUS;
                        subs->reason.s = "polite-block";
                        subs->reason.len = 12;
                        break;
                case SH_ACTION_ALLOW:
                        subs->status = ACTIVE_STATUS;
                        subs->reason.s = NULL;
                        subs->reason.len = 0;
                        break;
                default:
                        LM_ERR("unknown subscription handling action\n");
                        subs->status = PENDING_STATUS;
                        subs->reason.s = NULL;
                        subs->reason.len = 0;
                        break;
        }

        LM_INFO("Subscription from %.*s to %.*s is %s\n", watcher.len, watcher.s,
                                                          subs->pres_uri.len, subs->pres_uri.s,
                                                          subs_strstatus(subs));

done:
        if (watcher.s)
                pkg_free(watcher.s);
	if (sub_handling)
		xmlFree(sub_handling);
	xmlFreeDoc(xcap_tree);
	return ret;
}
Esempio n. 3
0
int dbt_query(db1_con_t* _h, db_key_t* _k, db_op_t* _op, db_val_t* _v, 
			db_key_t* _c, int _n, int _nc, db_key_t _o, db1_res_t** _r)
{
	dbt_table_p _tbc = NULL;
	dbt_row_p _drp = NULL;
	dbt_result_p _dres = NULL;
	int result = 0;
	
	int *lkey=NULL, *lres=NULL;
	
	db_key_t *_o_k=NULL;    /* columns in order-by */
	char *_o_op=NULL;       /* operators for oder-by */
	int _o_n;               /* no of elements in order-by */
	int *_o_l=NULL;         /* column selection for order-by */
	int _o_nc;              /* no of elements in _o_l but not lres */

	if ((!_h) || (!_r) || !CON_TABLE(_h))
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}
	*_r = NULL;
	

	if (_o)
	{
		if (dbt_parse_orderbyclause(&_o_k, &_o_op, &_o_n, _o) < 0)
			return -1;
	}

	/* lock database */
	_tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(!_tbc)
	{
		LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
		return -1;
	}


	if(!_tbc || _tbc->nrcols < _nc)
	{
		LM_ERR("table %s not loaded! (too few columns)\n", CON_TABLE(_h)->s);
		goto error;
	}
	if(_k)
	{
		lkey = dbt_get_refs(_tbc, _k, _n);
		if(!lkey)
			goto error;
	}
	if(_c)
	{
		lres = dbt_get_refs(_tbc, _c, _nc);
		if(!lres)
			goto error;
	}
	if(_o_k)
	{
		_o_l = dbt_get_refs(_tbc, _o_k, _o_n);
		if (!_o_l)
			goto error;
		/* enlarge select-columns lres by all order-by columns, _o_nc is how many */
		if (dbt_mangle_columnselection(&lres, &_nc, &_o_nc, _o_l, _o_n) < 0)
			goto error;
	}

	LM_DBG("new res with %d cols\n", _nc);
	_dres = dbt_result_new(_tbc, lres, _nc);
	
	if(!_dres)
		goto error;
	
	_drp = _tbc->rows;
	while(_drp)
	{
		if(dbt_row_match(_tbc, _drp, lkey, _op, _v, _n))
		{
			if(dbt_result_extract_fields(_tbc, _drp, lres, _dres))
			{
				LM_ERR("failed to extract result fields!\n");
				goto clean;
			}
		}
		_drp = _drp->next;
	}

	dbt_table_update_flags(_tbc, DBT_TBFL_ZERO, DBT_FL_IGN, 1);
	
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

	if (_o_l)
	{
		if (_dres->nrrows > 1)
		{
			if (dbt_sort_result(_dres, _o_l, _o_op, _o_n, lres, _nc) < 0)
				goto error_nounlock;
		}

		/* last but not least, remove surplus columns */
		if (_o_nc)
			dbt_project_result(_dres, _o_nc);
	}


	/* dbt_result_print(_dres); */
	
	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	if(_o_k)
 		pkg_free(_o_k);
 	if(_o_op)
 		pkg_free(_o_op);
 	if(_o_l)
 		pkg_free(_o_l);

	result = dbt_get_result(_r, _dres);
	if(result != 0)
		dbt_result_free(_dres);

	return result;

error:
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
error_nounlock:
	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	if(_o_k)
		pkg_free(_o_k);
	if(_o_op)
		pkg_free(_o_op);
	if(_o_l)
		pkg_free(_o_l);
	if(_dres)
		dbt_result_free(_dres);
	LM_ERR("failed to query the table!\n");

	return -1;

clean:
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	if(_o_k)
		pkg_free(_o_k);
	if(_o_op)
		pkg_free(_o_op);
	if(_o_l)
		pkg_free(_o_l);
	if(_dres)
		dbt_result_free(_dres);

	return -1;
}
Esempio n. 4
0
void cmd_pipe_cb(int fd, short event, void *arg)
{
	struct jsonrpc_pipe_cmd *cmd;
	/* struct event *ev = (struct event*)arg; */

	if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
		LM_ERR("failed to read from command pipe: %s\n", strerror(errno));
		return;
	}

	json_object *params = json_tokener_parse(cmd->params);
	json_object *payload = NULL;
	jsonrpc_request_t *req = NULL;

	if (cmd->notify_only) {
		payload = build_jsonrpc_notification(cmd->method, params);
	} else {
		req = build_jsonrpc_request(cmd->method, params, (char*)cmd, res_cb);
		if (req)
			payload = req->payload;
	}

	if (!payload) {
		LM_ERR("Failed to build jsonrpc_request_t (method: %s, params: %s)\n", cmd->method, cmd->params);	
		return;
	}
	char *json = (char*)json_object_get_string(payload);

	char *ns; size_t bytes;
	bytes = netstring_encode_new(&ns, json, (size_t)strlen(json));

	struct jsonrpc_server_group *g;
	int sent = 0;
	for (g = server_group; g != NULL; g = g->next_group)
	{
		struct jsonrpc_server *s, *first = NULL;
		for (s = g->next_server; s != first; s = s->next)
		{
			if (first == NULL) first = s;
			if (s->status == JSONRPC_SERVER_CONNECTED) {
				if (send(s->socket, ns, bytes, 0) == bytes)
				{
					sent = 1;
					break;
				} else {
					handle_server_failure(s);
				}
			}
			g->next_server = s->next;
		}
		if (sent) {
			break;
		} else {
			LM_WARN("Failed to send on priority group %d... proceeding to next priority group.\n", g->priority);
		}
	}

	if (sent && req) {
		int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);

		if (timerfd == -1) {
			LM_ERR("Could not create timerfd.");
			return;
		}

		req->timerfd = timerfd;
		struct itimerspec *itime = pkg_malloc(sizeof(struct itimerspec));
		CHECK_MALLOC_VOID(itime);
		itime->it_interval.tv_sec = 0;
		itime->it_interval.tv_nsec = 0;

		itime->it_value.tv_sec = JSONRPC_TIMEOUT/1000;
		itime->it_value.tv_nsec = (JSONRPC_TIMEOUT % 1000) * 1000000;
		if (timerfd_settime(timerfd, 0, itime, NULL) == -1) 
		{
			LM_ERR("Could not set timer.");
			return;
		}
		pkg_free(itime);
		struct event *timer_ev = pkg_malloc(sizeof(struct event));
		CHECK_MALLOC_VOID(timer_ev);
		event_set(timer_ev, timerfd, EV_READ, timeout_cb, req); 
		if(event_add(timer_ev, NULL) == -1) {
			LM_ERR("event_add failed while setting request timer (%s).", strerror(errno));
			return;
		}
		req->timer_ev = timer_ev;
	} else if (!sent) {
		LM_ERR("Request could not be sent... no more failover groups.\n");
		if (req) {
			json_object *error = json_object_new_string("failure");
			void_jsonrpc_request(req->id);
			req->cbfunc(error, req->cbdata, 1);
		}
	}

	pkg_free(ns);
	json_object_put(payload);
}
Esempio n. 5
0
/** Frees a hdr_field structure.
 * WARNING: it frees only parsed (and not name.s, body.s)
 */
void clean_hdr_field(struct hdr_field* const hf)
{
	void** h_parsed;

	if (hf->parsed){
		h_parsed=&hf->parsed; /* strict aliasing warnings workarround */
		switch(hf->type){
		/* headers with pkg alloc for parsed structure (alphabetic order) */
		case HDR_ACCEPT_T:
			pkg_free(hf->parsed);
			break;

		case HDR_ALLOW_T:
			free_allow_header(hf);
			break;

		case HDR_AUTHORIZATION_T:
			free_credentials((auth_body_t**)h_parsed);
			break;

		case HDR_CONTACT_T:
			free_contact((contact_body_t**)h_parsed);
			break;

		case HDR_CONTENTDISPOSITION_T:
			free_disposition( ((struct disposition**)h_parsed));
			break;

		case HDR_CSEQ_T:
			free_cseq(hf->parsed);
			break;

		case HDR_DATE_T:
			free_date(hf->parsed);
			break;

		case HDR_DIVERSION_T:
			free_to(hf->parsed);
			break;

		case HDR_EVENT_T:
			free_event((event_t**)h_parsed);
			break;

		case HDR_EXPIRES_T:
			free_expires((exp_body_t**)h_parsed);
			break;

		case HDR_FROM_T:
			free_to(hf->parsed);
			break;

		case HDR_IDENTITY_INFO_T:
			free_identityinfo(hf->parsed);
			break;

		case HDR_IDENTITY_T:
			free_identity(hf->parsed);
			break;

		case HDR_PAI_T:
			free_pai_ppi_body(hf->parsed);
			break;

		case HDR_PPI_T:
			free_pai_ppi_body(hf->parsed);
			break;

		case HDR_PROXYAUTH_T:
			free_credentials((auth_body_t**)h_parsed);
			break;

		case HDR_RECORDROUTE_T:
			free_rr((rr_t**)h_parsed);
			break;

		case HDR_REFER_TO_T:
			free_to(hf->parsed);
			break;

		case HDR_ROUTE_T:
			free_rr((rr_t**)h_parsed);
			break;

		case HDR_RPID_T:
			free_to(hf->parsed);
			break;

		case HDR_SESSIONEXPIRES_T:
			hdr_free_parsed(h_parsed);
			break;

		case HDR_SIPIFMATCH_T:
			free_sipifmatch((str **)h_parsed);
			break;

		case HDR_SUBSCRIPTION_STATE_T:
			free_subscription_state((subscription_state_t**)h_parsed);
			break;

		case HDR_SUPPORTED_T:
			hdr_free_parsed(h_parsed);
			break;

		case HDR_TO_T:
			free_to(hf->parsed);
			break;

		case HDR_VIA_T:
			free_via_list(hf->parsed);
			break;

		/* headers with no alloc for parsed structure */
		case HDR_CALLID_T:
		case HDR_MAXFORWARDS_T:
		case HDR_CONTENTTYPE_T:
		case HDR_CONTENTLENGTH_T:
		case HDR_RETRY_AFTER_T:
		case HDR_REQUIRE_T:
		case HDR_PROXYREQUIRE_T:
		case HDR_UNSUPPORTED_T:
		case HDR_ACCEPTLANGUAGE_T:
		case HDR_ORGANIZATION_T:
		case HDR_PRIORITY_T:
		case HDR_SUBJECT_T:
		case HDR_USERAGENT_T:
		case HDR_SERVER_T:
		case HDR_MIN_SE_T:
		case HDR_ACCEPTCONTACT_T:
		case HDR_ALLOWEVENTS_T:
		case HDR_CONTENTENCODING_T:
		case HDR_REFERREDBY_T:
		case HDR_REJECTCONTACT_T:
		case HDR_REQUESTDISPOSITION_T:
		case HDR_WWW_AUTHENTICATE_T:
		case HDR_PROXY_AUTHENTICATE_T:
		case HDR_PATH_T:
		case HDR_PRIVACY_T:
		case HDR_REASON_T:
			break;

		default:
			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
			    hf->type);
			break;
		}
	}
}
Esempio n. 6
0
int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	int flag_member = 0;
	int size = 0;
	int i = 0;
	int add_domain = 0;
	int add_sip = 0;
	str uri = {0, 0};
	str body;
	str room_name;
	struct sip_uri inv_uri;
	del_member_t *cback_param = NULL;
	int result;


	size = cmd->param[0].len+2 ;	
	add_domain = 1;
	add_sip = 0;
	while (i<size )
	{
		if(cmd->param[0].s[i]== '@')
		{	
			add_domain = 0;
			break;
		}
		i++;
	}

	if(add_domain)
		size += dst->host.len;

	if(cmd->param[0].len<4 || strncasecmp(cmd->param[0].s, "sip:", 4)!=0)
	{
		size += 4;
		add_sip = 1;
	}
		
	uri.s = (char*)pkg_malloc(size *sizeof(char));
	if(uri.s == NULL)
	{
		LM_ERR("no more pkg memory\n");
		goto error;
	}
	size= 0;
	if(add_sip)
	{	
		strcpy(uri.s, "sip:");
		size=4;
	}
		
	memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
	size += cmd->param[0].len;

	if(add_domain)
	{	
		uri.s[size] = '@';
		size++;
		memcpy(uri.s+ size, dst->host.s, dst->host.len);
		size+= dst->host.len;
	}
	uri.len = size;

	if(parse_uri(uri.s, uri.len, &inv_uri)!=0)
	{
		LM_ERR("bad uri [%.*s]!\n", uri.len, uri.s);
		goto error;
	}
					
	room_name = (cmd->param[1].s)?cmd->param[1]:dst->user;
	room = imc_get_room(&room_name, &dst->host);				
	if(room== NULL || (room->flags&IMC_ROOM_DELETED))
	{
		LM_ERR("the room does not exist [%.*s]!\n",
				room_name.len, room_name.s);
		goto error;
	}			
	member= imc_get_member(room, &src->user, &src->host);

	if(member==NULL)
	{
		LM_ERR("user [%.*s] is not member of[%.*s]!\n",
			src->user.len, src->user.s, room_name.len, room_name.s);
		goto error;
	}
	if(!(member->flags & IMC_MEMBER_OWNER) &&
			!(member->flags & IMC_MEMBER_ADMIN))
	{
		LM_ERR("user [%.*s] has no right to invite"
				" other users!\n", src->user.len, src->user.s);
		goto error;
	}
    
	member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
	if(member!=NULL)
	{
		LM_ERR("user [%.*s] is already member"
				" of the room!\n", inv_uri.user.len, inv_uri.user.s);
		goto error;
	}
		
	flag_member |= IMC_MEMBER_INVITED;		
	member=imc_add_member(room, &inv_uri.user, &inv_uri.host, &inv_uri.user /* TODO fullname dummy */, flag_member);
	if(member == NULL)
	{
		LM_ERR("adding member [%.*s]\n",
				inv_uri.user.len, inv_uri.user.s);
		goto error;	
	}
	
	body.len = 13 + member->uri.len - 4/* sip: */ + 28;	
	if(body.len>=IMC_BUF_SIZE || member->uri.len>=IMC_BUF_SIZE
			|| room->uri.len>=IMC_BUF_SIZE)
	{
		LM_ERR("buffer size overflow\n");
		goto error;	
	}

	body.s = imc_body_buf;
	memcpy(body.s, "INVITE from: ", 13);
	memcpy(body.s+13, member->uri.s + 4, member->uri.len - 4);
	memcpy(body.s+ 9 + member->uri.len, "(Type: '#accept' or '#deny')", 28);	
	body.s[body.len] = '\0';			

	LM_DBG("to=[%.*s]\nfrom=[%.*s]\nbody=[%.*s]\n", 
			member->uri.len,member->uri.s,room->uri.len, room->uri.s,
			body.len, body.s);
				
	cback_param = (del_member_t*)shm_malloc(sizeof(del_member_t));
	if(cback_param==NULL)
	{
		LM_ERR("no more shm\n");
		goto error;	
	}
	memset(cback_param, 0, sizeof(del_member_t));
	cback_param->room_name = room->name;
	cback_param->room_domain = room->domain;
	cback_param->member_name = member->user;
	cback_param->member_domain = member->domain;
	cback_param->inv_uri = member->uri;
	/*?!?! possible race with 'remove user' */
	result= tmb.t_request(&imc_msg_type,				/* Request Method */
				&member->uri,							/* Request-URI */
				&member->uri,							/* To */
				&room->uri,								/* From */
				&imc_hdr_ctype,							/* Extra headers */
				&body,						            /* Message body */
				(outbound_proxy.s)?&outbound_proxy:NULL,/* outbound proxy*/
				imc_inv_callback,						/* callback function*/
				(void*)(cback_param)					/* callback param*/
			);				
	if(result< 0)
	{
		LM_ERR("in tm send request\n");
		shm_free(cback_param);
		goto error;
	}
	if(uri.s!=NULL)
		pkg_free(uri.s);

	imc_release_room(room);

	return 0;

error:
	if(uri.s!=0)
		pkg_free(uri.s);

	if(room!=NULL)
		imc_release_room(room);

	return -1;
}
Esempio n. 7
0
int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
{
	struct to_body *pto, TO = {0}, *pfrom = NULL;
	str to_uri;
	char* uri= NULL;
	str from_uri;
	struct hdr_field* hdr= NULL;
	str body;
	int is_terminated= 0;
	str id;
	ua_pres_t dialog;
	int event_flag= 0;

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

	LM_DBG("start...\n\n");

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		return -1;
	}

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

	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");
			goto error;
		}
		pto = &TO;
	}

	dialog.watcher_uri= &pto->uri;

	uri=(char*)pkg_malloc(sizeof(char)*( pto->uri.len+1));
	if(uri== NULL)
	{
		LM_ERR("no more memory\n");
		goto error;
	}
	memcpy(uri, pto->uri.s, pto->uri.len);
	uri[pto->uri.len]= '\0';
	to_uri.s= duri_sip_xmpp(uri);
	if(to_uri.s== NULL)
	{
		LM_ERR("while decoding sip uri in xmpp\n");
		pkg_free(uri);
		goto error;
	}
	to_uri.len= strlen(to_uri.s);
	pkg_free(uri);

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		goto error;
	}
	id=  pto->tag_value;
	dialog.from_tag= id;

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

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

	uri=(char*)pkg_malloc(sizeof(char)*( pfrom->uri.len+1));
	if(uri== NULL)
	{
		LM_ERR("no more memory\n");
		goto error;
	}
	memcpy(uri, pfrom->uri.s, pfrom->uri.len);
	uri[pfrom->uri.len]= '\0';

	from_uri.s= euri_sip_xmpp(uri);
	if(from_uri.s== NULL)
	{
		LM_ERR("while encoding sip uri in xmpp\n");
		pkg_free(uri);
		goto error;
	}
	from_uri.len= strlen(from_uri.s);
	pkg_free(uri);

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		goto error;
	}

	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= XMPP_SUBSCRIBE;
	if(msg->event->body.len== 8 &&
			(strncmp(msg->event->body.s,"presence",8 )==0))
		event_flag|= PRESENCE_EVENT;
	else
		if(msg->event->body.len== 14 &&
				(strncmp(msg->event->body.s,"presence.winfo",14 )==0))
			event_flag|= PWINFO_EVENT;
		else
		{
			LM_ERR("wrong event\n");
			goto error;
		}
	dialog.event= event_flag;

	if(pua_is_dialog(&dialog)< 0) // verify if within a stored dialog
	{
		LM_ERR("Notify in a non existing dialog\n");
		goto error;
	}
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{
		body.s= NULL;
		body.len= 0;
	}
	else
	{
		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 );
	}

	/* treat the two cases: event= presence & event=presence.winfo */
	if(event_flag & PRESENCE_EVENT)
	{
		LM_DBG("PRESENCE\n");
		hdr = msg->headers;
		while (hdr!= NULL)
		{
			if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
				break;
			hdr = hdr->next;
		}
		if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0)
		{
			/* chack if reason timeout => don't send notification */
			if(strncmp(hdr->body.s+11,"reason=timeout", 14)== 0)
			{
				LM_DBG("Received Notification with state"
						"terminated; reason= timeout=> don't send notification\n");
				return 1;
			}
			is_terminated= 1;

		}

		if(build_xmpp_content(&to_uri, &from_uri, &body, &id, is_terminated)< 0)
		{
			LM_ERR("in function build_xmpp_content\n");
			goto error;
		}
	}
	else
	{
		if(event_flag & PWINFO_EVENT)
		{
			LM_DBG("PRESENCE.WINFO\n");
			hdr = msg->headers;
			while (hdr!= NULL)
			{
				if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)
					break;
				hdr = hdr->next;
			}
			if(hdr && strncmp(hdr->body.s,"terminated", 10)== 0)
			{
				LM_DBG("Notify for presence.winfo with"
						" Subscription-State terminated- should not translate\n");
				goto error;
			}
			if(winfo2xmpp(&to_uri, &body, &id)< 0)
			{
				LM_ERR("while sending subscription\n");
				goto error;
			}

		}
		else
		{
			LM_ERR("Missing or unsupported event header field value\n");
			goto error;
		}

	}
	free_to_params(&TO);
	return 1;

error:
	free_to_params(&TO);
	return 0;
}
Esempio n. 8
0
/*
 * Initialize the perl interpreter.
 * This might later be used to reinit the module.
 */
PerlInterpreter *parser_init(void) {
	int argc = 0;
	char *argv[MAX_LIB_PATHS + 3];
	PerlInterpreter *new_perl = NULL;
	char *entry, *stop, *end;
	int modpathset_start = 0;
	int modpathset_end = 0;
	int i;

	new_perl = perl_alloc();

	if (!new_perl) {
		LM_ERR("could not allocate perl.\n");
		return NULL;
	}

	perl_construct(new_perl);

	argv[0] = ""; argc++; /* First param _needs_ to be empty */
	
	 /* Possible Include path extension by modparam */
	if (modpath && (strlen(modpath) > 0)) {
		modpathset_start = argc;

		entry = modpath;
		stop = modpath + strlen(modpath);
		for (end = modpath; end <= stop; end++) {
			if ( (end[0] == ':') || (end[0] == '\0') ) {
				end[0] = '\0';
				if (argc > MAX_LIB_PATHS) {
					LM_ERR("too many lib paths, skipping lib path: '%s'\n", entry);
				} else {
					LM_INFO("setting lib path: '%s'\n", entry);
					argv[argc] = pkg_malloc(strlen(entry)+20);
					sprintf(argv[argc], "-I%s", entry);
					modpathset_end = argc;
					argc++;
				}
				entry = end + 1;
			}
		}
	}

	argv[argc] = "-M"DEFAULTMODULE; argc++; /* Always "use" Kamailio.pm */

	argv[argc] = filename; /* The script itself */
	argc++;

	if (perl_parse(new_perl, xs_init, argc, argv, NULL)) {
		LM_ERR("failed to load perl file \"%s\".\n", argv[argc-1]);
		if (modpathset_start) {
			for (i = modpathset_start; i <= modpathset_end; i++) {
				pkg_free(argv[i]);
			}
		}
		return NULL;
	} else {
		LM_INFO("successfully loaded perl file \"%s\"\n", argv[argc-1]);
	}

	if (modpathset_start) {
		for (i = modpathset_start; i <= modpathset_end; i++) {
			pkg_free(argv[i]);
		}
	}
	perl_run(new_perl);

	return new_perl;

}
Esempio n. 9
0
/*!
 * \brief Parse SIP message and populate leg informations
 *
 * Parse SIP message and populate leg informations. 
 * \param dlg the dialog to add cseq, contact & record_route
 * \param msg sip message
 * \param t transaction
 * \param leg type of the call leg
 * \param tag SIP To tag
 * \return 0 on success, -1 on failure
 * \note for a request: get record route in normal order, for a reply get
 * in reverse order, skipping the ones from the request and the proxies' own
 */
int populate_leg_info( struct dlg_cell *dlg, struct sip_msg *msg,
	struct cell* t, unsigned int leg, str *tag)
{
	unsigned int skip_recs;
	str cseq;
	str contact;
	str rr_set;

	dlg->bind_addr[leg] = msg->rcv.bind_address;

	/* extract the cseq number as string */
	if (leg==DLG_CALLER_LEG) {
		if((!msg->cseq && (parse_headers(msg,HDR_CSEQ_F,0)<0 || !msg->cseq))
			|| !msg->cseq->parsed){
			LM_ERR("bad sip message or missing CSeq hdr :-/\n");
			goto error0;
		}
		cseq = (get_cseq(msg))->number;
	} else {
		/* use the same as in request */
		cseq = dlg->cseq[DLG_CALLEE_LEG];
	}

	/* extract the contact address */
	if (!msg->contact&&(parse_headers(msg,HDR_CONTACT_F,0)<0||!msg->contact)){
		LM_ERR("bad sip message or missing Contact hdr\n");
		goto error0;
	}
	if ( parse_contact(msg->contact)<0 ||
	((contact_body_t *)msg->contact->parsed)->contacts==NULL ||
	((contact_body_t *)msg->contact->parsed)->contacts->next!=NULL ) {
		LM_ERR("bad Contact HDR\n");
		goto error0;
	}
	contact = ((contact_body_t *)msg->contact->parsed)->contacts->uri;

	/* extract the RR parts */
	if(!msg->record_route && (parse_headers(msg,HDR_EOH_F,0)<0)  ){
		LM_ERR("failed to parse record route header\n");
		goto error0;
	}

	if (leg==DLG_CALLER_LEG) {
		skip_recs = 0;
	} else {
		/* was the 200 OK received or local generated */
		skip_recs = dlg->from_rr_nb +
			((t->relayed_reply_branch>=0)?
				((t->uac[t->relayed_reply_branch].flags&TM_UAC_FLAG_R2)?2:
				 ((t->uac[t->relayed_reply_branch].flags&TM_UAC_FLAG_RR)?1:0))
				:0);
	}

	if(msg->record_route){
		if( print_rr_body(msg->record_route, &rr_set, leg,
							&skip_recs) != 0 ){
			LM_ERR("failed to print route records \n");
			goto error0;
		}
	} else {
		rr_set.s = 0;
		rr_set.len = 0;
	}

	if(leg==DLG_CALLER_LEG)
		dlg->from_rr_nb = skip_recs;

	LM_DBG("route_set %.*s, contact %.*s, cseq %.*s and bind_addr %.*s\n",
		rr_set.len, rr_set.s, contact.len, contact.s,
		cseq.len, cseq.s,
		msg->rcv.bind_address->sock_str.len,
		msg->rcv.bind_address->sock_str.s);

	if (dlg_set_leg_info( dlg, tag, &rr_set, &contact, &cseq, leg)!=0) {
		LM_ERR("dlg_set_leg_info failed\n");
		if (rr_set.s) pkg_free(rr_set.s);
		goto error0;
	}

	if (rr_set.s) pkg_free(rr_set.s);

	return 0;
error0:
	return -1;
}
/**
 * Query a table for specified rows.
 * \param _h structure representing database connection
 * \param _k key names
 * \param _op operators
 *\param  _v values of the keys that must match
 * \param _c column names to return
 * \param _n number of key=values pairs to compare
 * \param _nc number of columns to return
 * \param _o order by the specified column
 * \param _r pointer to a structure representing the result
 * \return zero on success, negative value on failure
 */
int erlang_srdb1_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
	     const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
	     const db_key_t _o, db1_res_t** _r) {
	ei_x_buff argbuf,retbuf;
	int retcode,i,j,x;
	int n_cols,n_rows,len;
	db1_res_t *res;
	db_row_t *rows = NULL, *row;
	db_val_t *val;
	char atom[MAXATOMLEN], *p;
	ei_term term;
	int ei_type,size;
	str *sname;

	if (!_h || !_r) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}
	*_r=NULL;
	LM_DBG("erlang_srdb1_query table %.*s\n",CON_TABLE(_h)->len, CON_TABLE(_h)->s);
	ei_x_new(&argbuf);
	//encode tuple {db_op, table, [cols], [params]}
	ei_x_encode_tuple_header(&argbuf, 5);
	ei_x_encode_atom(&argbuf,"select");
	ei_x_encode_atom_len(&argbuf,CON_TABLE(_h)->s,CON_TABLE(_h)->len);

	srdb1_encode_c(_c, _nc, &argbuf);
	srdb1_encode_k(_k, _op, _v, _n, &argbuf);
//	ei_x_encode_atom_len(&argbuf,_o->s,_o->len);
	ei_x_encode_list_header(&argbuf, 0);

	retcode=erl_bind.do_erlang_call(&(CON_ERLANG(_h)->con),&(CON_ERLANG(_h)->regname), &argbuf, &retbuf);
	ei_x_free(&argbuf);
	if (retcode<0) {
		if(retbuf.buff) shm_free(retbuf.buff);
		return retcode;
	}
	// we have a tuple there:
	ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &i);
	x=retbuf.index;
	ei_skip_term(retbuf.buff, &x);
	LM_DBG("erlang_srdb1_query: position of end of field list should be %d\n",x);
	//first is list of 5-element tuples containing name and type of field
	ei_decode_list_header(retbuf.buff, &(retbuf.index), &n_cols);
	LM_DBG("erlang_srdb1_query: length -f field_list is %d\n",n_cols);
	res=db_new_result();
	if (db_allocate_columns(res, n_cols) != 0) {
		LM_ERR("erlang_srdb1_query: db_allocate_columns failed\n");
		goto error;
	}
	RES_COL_N(res) = n_cols;
	for(i=0; i < n_cols; i++) {
		x=retbuf.index;
		ei_skip_term(retbuf.buff, &x);
		LM_DBG("erlang_srdb1_query: position of end of this field should be %d\n",x);
		ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &j);
		if( j!=5) LM_ERR("erlang_srdb1_query name&type list element tuple is not 5\n");
		ei_decode_atom(retbuf.buff, &(retbuf.index), atom);  //1  name
		len=strlen(atom);
		sname = (str*)pkg_malloc(sizeof(str)+len+1);
		if (!sname) {
			LM_ERR("no private memory left\n");
			goto error;
		}
		sname->len = len;
		sname->s = (char*)sname + sizeof(str);
		memcpy(sname->s, atom, len);
		sname->s[len] = '\0';
		RES_NAMES(res)[i] = sname;
		LM_DBG("decoded header %d, fieled 1: %s\n",i,atom);
		ei_decode_atom(retbuf.buff, &(retbuf.index), atom); //2 type atom
		if(strcmp("int",atom)==0) { RES_TYPES(res)[i]=DB1_INT; }
		if(strcmp("string",atom)==0) { RES_TYPES(res)[i]=DB1_STRING; }
		if(strcmp("float",atom)==0) { RES_TYPES(res)[i]=DB1_DOUBLE; }
		if(strcmp("datetime",atom)==0) { RES_TYPES(res)[i]=DB1_DATETIME; }
//		if(strcmp("string",atom)==0) { RES_TYPES(res)[i]=DB1_BLOB; }
		ei_skip_term(retbuf.buff, &(retbuf.index));  //3 size (ignored)
		ei_skip_term(retbuf.buff, &(retbuf.index));  //4 default value (ignored)
		ei_skip_term(retbuf.buff, &(retbuf.index));  //3 null status (ignored)
		LM_DBG("end of %d record: %d\n",i,retbuf.index);
	}
	ei_decode_ei_term(retbuf.buff, &(retbuf.index), &term); // List tail,
	LM_DBG("erlang_srdb1_query: position after scanning is %d\n",retbuf.index);
	//now rows, list of tuples
	ei_decode_list_header(retbuf.buff, &(retbuf.index), &n_rows);
	LM_DBG("erlang_srdb1_query values list size is %d\n",n_rows);
	if (n_rows<=0) {
		LM_DBG("erlang_srdb1_query no rows returned\n");
		RES_ROWS(res) = NULL;
		RES_NUM_ROWS(res)=0;
		*_r=res;
		return 0;
	}
	RES_NUM_ROWS(res)=n_rows;
	rows = pkg_realloc(rows, sizeof(db_row_t) * n_rows);
	if (rows == NULL) {
		LM_ERR("erlang_srdb1_query: pkg_realloc rows failed\n");
		goto error;
	}
	RES_ROWS(res) = rows;
	for(i=0; i < n_rows; i++) {
		RES_ROW_N(res)=i+1;
		row = &RES_ROWS(res)[i];
		if (db_allocate_row(res, row) != 0) {
			LM_ERR("erlang_srdb1_query: db_allocate_row failed for row %d\n",i);
			goto error;
		}
		ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &j);
		if(j!=n_cols) {
			LM_ERR("erlang_srdb1_query: mismatch:values list element tuple size is %d n_cols from header was %d\n",j, n_cols);
		}
		for (j = 0, val = ROW_VALUES(row); j < RES_COL_N(res); j++, val++) {
			VAL_TYPE(val) = RES_TYPES(res)[j];
			VAL_NULL(val) = 0;
			VAL_FREE(val) = 0;
			retcode=ei_get_type_internal(retbuf.buff, &(retbuf.index), &ei_type, &size);
			if (retcode < 0) {
				LM_ERR("erlang_srdb1_query: error getting type for element %d %d\n",i,j);
				goto error;
			}
			LM_DBG("erlang_srdb1_query: element %d %d ei_type=%d size=%d\n",i,j,ei_type, size);
			switch(ei_type) {
				case ERL_SMALL_INTEGER_EXT:
				case ERL_INTEGER_EXT:
					retcode=ei_decode_long(retbuf.buff, &(retbuf.index), &VAL_INT(val));
					if(retcode < 0) goto error;
					LM_DBG("decoded interger %d\n",VAL_INT(val));
					break;
				case ERL_FLOAT_EXT:
				case NEW_FLOAT_EXT:
					retcode=ei_decode_double(retbuf.buff, &(retbuf.index), &VAL_DOUBLE(val));
					if(retcode < 0) goto error;
					LM_DBG("decoded float %f\n",VAL_DOUBLE(val));
					break;
				case ERL_ATOM_EXT:
				case ERL_SMALL_ATOM_EXT:
				case ERL_ATOM_UTF8_EXT:
				case ERL_SMALL_ATOM_UTF8_EXT:
					p=pkg_malloc(size+1);
					if(!p) { LM_ERR("erlang_srdb1_query: no memory\n"); goto error; }
					retcode=ei_decode_atom(retbuf.buff, &(retbuf.index), p);
					if(retcode < 0) {
						pkg_free(p);
						goto error;
					}
					LM_DBG("decoded small_atom_utf %s\n",p);
					VAL_STRING(val)=p;
					VAL_FREE(val)=1;
					break;
				case ERL_STRING_EXT:
					p=pkg_malloc(size+1);
					if(!p) { LM_ERR("erlang_srdb1_query: no memory\n"); goto error; }
					retcode=ei_decode_string(retbuf.buff, &(retbuf.index), p);
					if(retcode < 0) {
						pkg_free(p);
						goto error;
					}
					LM_DBG("decoded string %s\n",p);
					VAL_STRING(val)=p;
					VAL_FREE(val)=1;
					break;
				case ERL_SMALL_TUPLE_EXT:
				case ERL_LARGE_TUPLE_EXT:
					LM_DBG("got tuple)\n");
					if (VAL_TYPE(val)==DB1_DATETIME) {
					    struct tm tm;
					    LM_DBG("and col type is datetime\n");
					    retcode=ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &x);
					    if(retcode < 0) goto error;
					    retcode=ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &x);
					    if(retcode < 0) goto error;
					    retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_year);tm.tm_year -=1900;
					    if(retcode < 0) goto error;
					    retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_mon); tm.tm_mon -=1;
					    if(retcode < 0) goto error;
					    retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_mday);
					    if(retcode < 0) goto error;
					    retcode=ei_decode_tuple_header(retbuf.buff, &(retbuf.index), &x);
					    if(retcode < 0) goto error;
					    retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_hour);
					    if(retcode < 0) goto error;
					    retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_min);
					    if(retcode < 0) goto error;
					    retcode=ei_decode_long(retbuf.buff, &(retbuf.index), (long int *)&tm.tm_sec);
					    if(retcode < 0) goto error;
					    VAL_TIME(val)=mktime(&tm);
					    break;
					}
					LM_ERR("erlang_srdb1_query: got tuple but valtype is not datetime element %d in row %d in response\n",j,i);
					break;
				case ERL_REFERENCE_EXT:
				case ERL_NEW_REFERENCE_EXT:
				case ERL_PORT_EXT:
				case ERL_PID_EXT:
				case ERL_NIL_EXT:
				case ERL_LIST_EXT:
				case ERL_BINARY_EXT:
				case ERL_SMALL_BIG_EXT:
				case ERL_LARGE_BIG_EXT:
				case ERL_NEW_FUN_EXT:
				case ERL_FUN_EXT:
				default:
				    LM_ERR("erlang_srdb1_query: don't know how to handle element %d in row %d in response\n",j,i);
			}
		}
	}
	ei_decode_ei_term(retbuf.buff, &(retbuf.index), &term); // List tail,
	*_r=res;
	return 0;
error:
	if (res)
		db_free_result(res);
	LM_ERR("erlang_srdb1_query: Failed\n");
	return -1;
}
//temporary
void erlang_srdb1_free_connection(struct erlang_connection* con) {
	LM_DBG("erlang_free_connection %p \n",con);
	free_db_id(con->hdr.id);
	pkg_free(con);
	return;
}
Esempio n. 12
0
int update_phtable(presentity_t* presentity, str pres_uri, str body)
{
	char* sphere= NULL;
	unsigned int hash_code;
	pres_entry_t* p;
	int ret= 0;
	str* xcap_doc= NULL;

	/* get new sphere */
	sphere= extract_sphere(body);
	if(sphere==NULL)
	{
		LM_DBG("no sphere defined in new body\n");
		return 0;
	}

	/* search for record in hash table */
	hash_code= core_hash(&pres_uri, NULL, phtable_size);

	lock_get(&pres_htable[hash_code].lock);

	p= search_phtable(&pres_uri, presentity->event->evp->parsed, hash_code);
	if(p== NULL)
	{
		lock_release(&pres_htable[hash_code].lock);
		goto done;
	}

	if(p->sphere)
	{
		if(strcmp(p->sphere, sphere)!= 0)
		{
			/* new sphere definition */
			shm_free(p->sphere);
		}
		else
		{
			/* no change in sphere definition */
			lock_release(&pres_htable[hash_code].lock);
			pkg_free(sphere);
			return 0;
		}

	}


	p->sphere= (char*)shm_malloc(strlen(sphere)+ 1);
	if(p->sphere== NULL)
	{
		lock_release(&pres_htable[hash_code].lock);
		ret= -1;
		goto done;
	}
	strcpy(p->sphere, sphere);

	lock_release(&pres_htable[hash_code].lock);

	/* call for watchers status update */

	if(presentity->event->get_rules_doc(&presentity->user, &presentity->domain,
				&xcap_doc)< 0)
	{
		LM_ERR("failed to retreive xcap document\n");
		ret= -1;
		goto done;
	}

	update_watchers_status(pres_uri, presentity->event, xcap_doc);


done:

	if(xcap_doc)
	{
		if(xcap_doc->s)
			pkg_free(xcap_doc->s);
		pkg_free(xcap_doc);
	}

	if(sphere)
		pkg_free(sphere);
	return ret;
}
Esempio n. 13
0
static int
UseMediaProxy(struct sip_msg* msg, char* str1, char* str2)
{
    str sdp, sessionIP, signalingIP, callId, userAgent, tokens[64];
    str fromDomain, toDomain, fromAddr, toAddr, fromTag, toTag, domain;
    char *ptr, *command, *result, *agent, *fromType, *toType, *info;
    int streamCount, i, port, count, portCount, cmdlen, infolen, status;
    StreamInfo streams[64], stream;
    Bool request;

    if (msg->first_line.type == SIP_REQUEST) {
        request = True;
    } else if (msg->first_line.type == SIP_REPLY) {
        request = False;
    } else {
        return -1;
    }

    if (!getCallId(msg, &callId)) {
        LM_ERR("can't get Call-Id\n");
        return -1;
    }

    status = getSDPMessage(msg, &sdp);
    // status = -1 is error, -2 is missing SDP body
    if (status < 0)
        return status;

    if (!getSessionLevelMediaIP(&sdp, &sessionIP)) {
        LM_ERR("failed to parse the SDP message\n");
        return -1;
    }

    streamCount = getMediaStreams(&sdp, &sessionIP, streams, 64);
    if (streamCount == -1) {
        LM_ERR("can't extract media streams from the SDP message\n");
        return -1;
    }

    if (streamCount == 0)
        return 1; // there are no media streams. we have nothing to do.

    fromDomain = getFromDomain(msg);
    fromType   = (isFromLocal(msg, NULL, NULL)>0) ? "local" : "remote";
    fromAddr   = getFromAddress(msg);
    toAddr     = getToAddress(msg);
    fromTag    = getFromTag(msg);
    toTag      = getToTag(msg);
    userAgent  = getUserAgent(msg);
    if (request) {
        toDomain = getDestinationDomain(msg); // call only for requests
        toType = (isDestinationLocal(msg, NULL, NULL)>0) ? "local" : "remote";
    } else {
        toDomain.s = "unknown";
        toDomain.len = 7;
        toType = "unknown";
    }

    signalingIP = getSignalingIP(msg);
    domain = getMediaproxyDomain(msg);

    infolen = fromAddr.len + toAddr.len + fromTag.len + toTag.len +
        domain.len + 64;

    cmdlen = callId.len + signalingIP.len + fromDomain.len + toDomain.len +
        userAgent.len*3 + infolen + 128;

    for (i=0; i<streamCount; i++) {
        stream = streams[i];
        cmdlen += stream.ip.len + stream.port.len + stream.type.len + 4;
    }

    command = pkg_malloc(cmdlen);
    if (!command) {
        LM_ERR("out of memory\n");
        return -1;
    }

    if (request)
        count = sprintf(command, "request %.*s", callId.len, callId.s);
    else
        count = sprintf(command, "lookup %.*s", callId.len, callId.s);

    for (i=0, ptr=command+count; i<streamCount; i++) {
        char c = (i==0 ? ' ' : ',');
        count = sprintf(ptr, "%c%.*s:%.*s:%.*s", c,
                        streams[i].ip.len, streams[i].ip.s,
                        streams[i].port.len, streams[i].port.s,
                        streams[i].type.len, streams[i].type.s);
        ptr += count;
    }

    agent = encodeQuopri(userAgent);
    if (!agent) {
        LM_ERR("out of memory\n");
        pkg_free(command);
        return -1;
    }

    info = pkg_malloc(infolen);
    if (!info) {
        LM_ERR("out of memory\n");
        pkg_free(command);
        pkg_free(agent);
        return -1;
    }

    sprintf(info, "from:%.*s,to:%.*s,fromtag:%.*s,totag:%.*s",
            fromAddr.len, fromAddr.s, toAddr.len, toAddr.s,
            fromTag.len, fromTag.s, toTag.len, toTag.s);

    if (domain.len) {
        strcat(info, ",domain:");
        strncat(info, domain.s, domain.len);
    }
    if (isRTPAsymmetric(userAgent)) {
        strcat(info, ",asymmetric");
    }

    snprintf(ptr, command + cmdlen - ptr, " %.*s %.*s %s %.*s %s %s info=%s\n",
             signalingIP.len, signalingIP.s, fromDomain.len, fromDomain.s,
             fromType, toDomain.len, toDomain.s, toType, agent, info);

    pkg_free(info);
    pkg_free(agent);

    result = sendMediaproxyCommand(command);

    pkg_free(command);

    if (result == NULL)
        return -1;

    count = getTokens(result, tokens, sizeof(tokens)/sizeof(str));

    if (count == 0) {
        LM_ERR("empty response from mediaproxy\n");
        return -1;
    } else if (count<streamCount+1) {
        if (request) {
            LM_ERR("insufficient ports returned from mediaproxy: got %d, "
                   "expected %d\n", count-1, streamCount);
            return -1;
        } else {
            LM_WARN("broken client. Called UA added extra media stream(s) "
                    "in the OK reply\n");
        }
    }

    if (sessionIP.s && !isAnyAddress(sessionIP)) {
        if (!replaceElement(msg, &sessionIP, &tokens[0])) {
            LM_ERR("failed to replace session-level media IP in the SDP body\n");
            return -1;
        }
    }

    portCount = min(count-1, streamCount);

    for (i=0; i<portCount; i++) {
        // check. is this really necessary?
        port = strtoint(&tokens[i+1]);
        if (port <= 0 || port > 65535) {
            LM_ERR("invalid port returned by mediaproxy: %.*s\n",
                   tokens[i+1].len, tokens[i+1].s);
            //return -1;
            continue;
        }

        if (streams[i].port.len!=1 || streams[i].port.s[0]!='0') {
            if (!replaceElement(msg, &(streams[i].port), &tokens[i+1])) {
                LM_ERR("failed to replace port in media stream number %d\n", i+1);
                return -1;
            }
        }

        if (streams[i].localIP && !isAnyAddress(streams[i].ip)) {
            if (!replaceElement(msg, &(streams[i].ip), &tokens[0])) {
                LM_ERR("failed to replace IP address in media stream number %d\n", i+1);
                return -1;
            }
        }
    }

    return 1;
}
Esempio n. 14
0
// Check if the requested asymmetrics file has changed and reload it if needed
static void
checkAsymmetricFile(AsymmetricClients *aptr)
{
    char buf[512], errbuf[256], *which;
    regex_t *re, **regs;
    int i, size, code;
    Bool firstTime = False;
    struct stat statbuf;
    FILE *file;
    str line;

    if (stat(aptr->file, &statbuf) < 0)
        return; // ignore missing file

    if (statbuf.st_mtime <= aptr->timestamp)
        return; // not changed

    which = (aptr == &sipAsymmetrics ? "SIP" : "RTP");

    if (!aptr->clients) {
        // if we are here the first time allocate memory to hold the regexps

        // initial size of array
        // (hopefully not reached so we won't need to realloc)
        size = 32;
        aptr->clients = (regex_t**)pkg_malloc(size*sizeof(regex_t**));
        if (!aptr->clients) {
            LM_WARN("cannot allocate memory for the %s asymmetric client list."
                    " %s asymmetric clients will not be handled properly.\n",
                    which, which);
            return; // ignore as it is not fatal
        }
        aptr->size  = size;
        aptr->count = 0;
        firstTime = True;
    } else {
        // else clean old stuff
        for (i=0; i<aptr->count; i++) {
            regfree(aptr->clients[i]);
            pkg_free(aptr->clients[i]);
            aptr->clients[i] = NULL;
        }
        aptr->count = 0;
    }

    // read new
    file = fopen(aptr->file, "r");
    i = 0; // this will count on which line are we in the file
    while (!feof(file)) {
        if (!fgets(buf, 512, file))
            break;
        i++;

        line.s = buf;
        line.len = strlen(buf);
        trim(&line);
        if (line.len == 0 || line.s[0] == '#')
            continue; // comment or empty line. ignore
        line.s[line.len] = 0;

        re = (regex_t*)pkg_malloc(sizeof(regex_t));
        if (!re) {
            LM_WARN("cannot allocate memory for all the %s asymmetric "
                    "clients listed in file. Some of them will not be "
                    "handled properly.\n", which);
            break;
        }
        code = regcomp(re, line.s, REG_EXTENDED|REG_ICASE|REG_NOSUB);
        if (code == 0) {
            if (aptr->count+1 > aptr->size) {
                size = aptr->size * 2;
                regs = aptr->clients;
                regs = (regex_t**)pkg_realloc(regs, size*sizeof(regex_t**));
                if (!regs) {
                    LM_WARN("cannot allocate memory for all the %s asymmetric "
                            "clients listed in file. Some of them will not be "
                            "handled properly.\n", which);
                    break;
                }
                aptr->clients = regs;
                aptr->size = size;
            }
            aptr->clients[aptr->count] = re;
            aptr->count++;
        } else {
            regerror(code, re, errbuf, 256);
            LM_WARN("cannot compile line %d of the %s asymmetric clients file "
                    "into a regular expression (will be ignored): %s",
                    i, which, errbuf);
            pkg_free(re);
        }
    }

    aptr->timestamp = statbuf.st_mtime;

    LM_INFO("%sloaded %s asymmetric clients file containing %d entr%s.\n",
            firstTime ? "" : "re", which, aptr->count,
            aptr->count==1 ? "y" : "ies");

}
Esempio n. 15
0
/*
 * Delete a row from table
 */
int dbt_delete(db1_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n)
{
	dbt_table_p _tbc = NULL;
	dbt_row_p _drp = NULL, _drp0 = NULL;
	int *lkey = NULL;

	if (!_h || !CON_TABLE(_h))
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}

	/* lock database */
	_tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(!_tbc)
	{
		LM_ERR("failed to load table <%.*s>!\n", CON_TABLE(_h)->len,
				CON_TABLE(_h)->s);
		return -1;
	}

	if(!_k || !_v || _n<=0)
	{
		LM_DBG("deleting all records\n");
		dbt_table_free_rows(_tbc);
		/* unlock databse */
		dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
		return 0;
	}

	lkey = dbt_get_refs(_tbc, _k, _n);
	if(!lkey)
		goto error;
	
	_drp = _tbc->rows;
	while(_drp)
	{
		_drp0 = _drp->next;
		if(dbt_row_match(_tbc, _drp, lkey, _o, _v, _n))
		{
			// delete row
			if(_drp->prev)
				(_drp->prev)->next = _drp->next;
			else
				_tbc->rows = _drp->next;
			if(_drp->next)
				(_drp->next)->prev = _drp->prev;
			_tbc->nrrows--;
			// free row
			dbt_row_free(_tbc, _drp);
		}
		_drp = _drp0;
	}

	dbt_table_update_flags(_tbc, DBT_TBFL_MODI, DBT_FL_SET, 1);
	
	/* dbt_print_table(_tbc, NULL); */
	
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

	if(lkey)
		pkg_free(lkey);
	
	return 0;
	
error:
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

	LM_ERR("failed to delete from table!\n");
	return -1;
}
Esempio n. 16
0
static int http_get_xcap_doc(str* user, str* domain, int type, str** doc)
{
	str body;
	str *doc_tmp;
	xcap_doc_sel_t doc_sel;
	xcap_serv_t* xs;
	xcap_get_req_t req;

	*doc = NULL;

        if (type != PRES_RULES && type != OMA_PRES_RULES)
        {
                LM_ERR("only pres-rules documents can be fetched though HTTP for now\n");
                goto error;
        }

	memset(&req, 0, sizeof(xcap_get_req_t));
	if(uandd_to_uri(*user, *domain, &doc_sel.xid) < 0)
	{
		LM_ERR("constructing uri\n");
		goto error;
	}

	if(pres_rules_auid.s && pres_rules_auid.len)
	{
		doc_sel.auid = pres_rules_auid;
	}
	else
	{
		doc_sel.auid.s = "pres-rules";
		doc_sel.auid.len = strlen(doc_sel.auid.s);
	}
	doc_sel.doc_type = pres_rules_doc_id;
	doc_sel.type = USERS_TYPE;

	if(pres_rules_filename.s && pres_rules_filename.len)
        {
		doc_sel.filename = pres_rules_filename;
        }
	else
	{
		doc_sel.filename.s = "index";
		doc_sel.filename.len = strlen(doc_sel.filename.s);
	}

	/* need the whole document so the node selector is NULL */
	/* don't know which is the authoritative server for the user
	 * so send request to all in the list */
	req.doc_sel = doc_sel;

	xs = xs_list;
	while (xs)
	{
		req.xcap_root = xs->addr;
		req.port = xs->port;
		if(xcap_GetNewDoc(req, *user, *domain, &body) < 0)
		{
			LM_ERR("while fetching data from xcap server\n");
                        pkg_free(doc_sel.xid.s);
			goto error;
		}
		if(body.s)
                {
		        /* if document found, stop searching */
			break;
                }
		xs = xs->next;
	}

        pkg_free(doc_sel.xid.s);

        if (body.s == NULL)
                goto error;

	doc_tmp = pkg_malloc(sizeof(*doc_tmp));
	if(doc_tmp == NULL)
	{
		LM_ERR("No more pkg memory\n");
		goto error;
	}
	doc_tmp->s = pkg_malloc(body.len);
	if(doc_tmp->s == NULL)
	{
		pkg_free(doc_tmp);
		LM_ERR("No more pkg memory\n");
		goto error;
	}
	memcpy(doc_tmp->s, body.s, body.len);
	doc_tmp->len = body.len;
	pkg_free(body.s);

        *doc = doc_tmp;
	return 0;

error:
        if (body.s)
                pkg_free(body.s);
	return -1;
}
Esempio n. 17
0
/*
 * Update a row in table
 */
int dbt_update(db1_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v,
	      db_key_t* _uk, db_val_t* _uv, int _n, int _un)
{
	dbt_table_p _tbc = NULL;
	dbt_row_p _drp = NULL;
	int i;
	int *lkey=NULL, *lres=NULL;

	if (!_h || !CON_TABLE(_h) || !_uk || !_uv || _un <= 0)
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}
	
	/* lock database */
	_tbc = dbt_db_get_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));
	if(!_tbc)
	{
		LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
		return -1;
	}

	if(_k)
	{
		lkey = dbt_get_refs(_tbc, _k, _n);
		if(!lkey)
			goto error;
	}
	lres = dbt_get_refs(_tbc, _uk, _un);
	if(!lres)
		goto error;
	_drp = _tbc->rows;
	while(_drp)
	{
		if(dbt_row_match(_tbc, _drp, lkey, _o, _v, _n))
		{ // update fields
			for(i=0; i<_un; i++)
			{
				if(dbt_is_neq_type(_tbc->colv[lres[i]]->type, _uv[i].type))
				{
					LM_ERR("incompatible types!\n");
					goto error;
				}
				
				if(dbt_row_update_val(_drp, &(_uv[i]),
							_tbc->colv[lres[i]]->type, lres[i]))
				{
					LM_ERR("cannot set v[%d] in c[%d]!\n",
							i, lres[i]);
					goto error;
				}
			}
		}
		_drp = _drp->next;
	}

	dbt_table_update_flags(_tbc, DBT_TBFL_MODI, DBT_FL_SET, 1);
	
	/* dbt_print_table(_tbc, NULL); */
	
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);

    return 0;

error:
	/* unlock database */
	dbt_release_table(DBT_CON_CONNECTION(_h), CON_TABLE(_h));

	if(lkey)
		pkg_free(lkey);
	if(lres)
		pkg_free(lres);
	
	LM_ERR("failed to update the table!\n");

	return -1;
}
Esempio n. 18
0
static inline int get_resource_list(str *username, str *domain, str *filename, str *selector,
                                    xmlNodePtr *rl_node, xmlDocPtr *xmldoc)
{
        static char path_buf[MAX_PATH_LEN+1];

        int checked = 0;
        str path;
        str *doc = NULL;
        str *etag = NULL;
	xmlXPathContextPtr xpathCtx = NULL;
	xmlXPathObjectPtr xpathObj = NULL;

	if (filename==NULL || username==NULL || domain==NULL)
	{
		LM_ERR("invalid parameters\n");
		return -1;
	}

        if (xcapDbGetDoc(username, domain, RESOURCE_LISTS, filename, NULL, &doc, &etag) < 0)
        {
		LM_DBG("No rl document found\n");
                return -1;
        }
	LM_DBG("rl document:\n%.*s\n", doc->len, doc->s);

	path.s = path_buf;
	path.len = 0;
	if (selector->s) {
            while (checked < selector->len && path.len <= MAX_PATH_LEN)
            {
                    if (selector->s[checked] == '/')
                    {
                            memcpy(path.s+path.len, "/xmlns:", 7);
                            path.len += 7;
                    }
                    else
                    {
                            path.s[path.len++] = selector->s[checked];
                    }
                    checked++;
            }
            path.s[path.len] = '\0';
            LM_DBG("path: %.*s", path.len, path.s);
        }

	*xmldoc = xmlParseMemory(doc->s, doc->len);
	if (*xmldoc == NULL)
	{
		LM_ERR("while parsing XML memory\n");
		goto error;
	}

	if(path.len == 0)
	{
		LM_ERR("no path specified\n");
		goto error;
	}

        /* TODO: move this to xcap module? */
        xpathCtx = xmlXPathNewContext(*xmldoc);
        if (xpathCtx == NULL)
        {
                LM_ERR("unable to create new XPath context");
                goto error;
        }

        if (xmlXPathRegisterNs(xpathCtx, BAD_CAST "xmlns", BAD_CAST "urn:ietf:params:xml:ns:resource-lists") != 0)
        {
                LM_ERR("unable to register xmlns\n");
                goto error;
        }

        xpathObj = xmlXPathEvalExpression(BAD_CAST path.s, xpathCtx);
        if (xpathObj == NULL)
        {
                LM_ERR("unable to evaluate path\n");
                goto error;
        }

        if (xpathObj->nodesetval == NULL || xpathObj->nodesetval->nodeNr <= 0)
        {
                LM_ERR("no nodes found\n");
                goto error;
        }
        if (xpathObj->nodesetval->nodeTab[0] != NULL && xpathObj->nodesetval->nodeTab[0]->type != XML_ELEMENT_NODE)
        {
                LM_ERR("no nodes of the correct type found\n");
                goto error;

        }

        *rl_node = xpathObj->nodesetval->nodeTab[0];

        xmlXPathFreeObject(xpathObj);
        xmlXPathFreeContext(xpathCtx);

        pkg_free(doc->s);
        pkg_free(doc);
        pkg_free(etag->s);
        pkg_free(etag);

        return 0;

error:
        if (doc != NULL)
        {
                if (doc->s != NULL)
                        pkg_free(doc->s);
                pkg_free(doc);
        }
        if (etag != NULL)
        {
                if (etag->s != NULL)
                        pkg_free(etag->s);
                pkg_free(etag);
        }
	if (xpathObj)
		xmlXPathFreeObject(xpathObj);
	if (xpathCtx)
		xmlXPathFreeContext(xpathCtx);
	if (*xmldoc)
		xmlFreeDoc(*xmldoc);
	return -1;
}
Esempio n. 19
0
int imc_handle_remove(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	str room_name;
	str body;
	str uri = {0, 0};
	int size =0;
	int i = 0;
	int add_domain = 0;
	int add_sip = 0;
	struct sip_uri inv_uri;

	size= cmd->param[0].len+2;
	add_domain = 1;
	while (i<size )
	{
		if(cmd->param[0].s[i]== '@')
		{	
			add_domain =0;
			break;
		}
		i++;
	}

	if(add_domain)
		size += dst->host.len;
	if(cmd->param[0].len<=4 || strncasecmp(cmd->param[0].s, "sip:", 4)!=0)
	{
		size+= 4;
		add_sip = 1;
	}

	uri.s = (char*)pkg_malloc(size*sizeof(char));
	if(uri.s == NULL)
	{
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	size= 0;
	if(add_sip)
	{	
		strcpy(uri.s, "sip:");
		size = 4;
	}
					
	memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
	size+= cmd->param[0].len;

	if(add_domain)
	{	
		uri.s[size] = '@';
		size++;
		memcpy(uri.s+size, dst->host.s, dst->host.len);
		size+= dst->host.len;
	}
	uri.len = size;

	if(parse_uri(uri.s, uri.len, &inv_uri)<0)
	{
		LM_ERR("invalid uri [%.*s]\n", uri.len, uri.s);
		goto error;
	}
					
	room_name = cmd->param[1].s?cmd->param[1]:dst->user;
	room= imc_get_room(&room_name, &dst->host);
	if(room==NULL || (room->flags&IMC_ROOM_DELETED))
	{
		LM_ERR("room [%.*s]does not exist!\n", room_name.len, room_name.s);
		goto error;
	}			

	/* verify if the user who sent the request is a member in the room
	 * and has the right to remove other users */
	member= imc_get_member(room, &src->user, &src->host);

	if(member== NULL)
	{
		LM_ERR("user [%.*s] is not member of room [%.*s]!\n", 
				src->user.len, src->user.s, room_name.len, room_name.s);
		goto error;
	}
	
	if(!(member->flags & IMC_MEMBER_OWNER) &&
		!(member->flags & IMC_MEMBER_ADMIN))
	{
			LM_ERR("user [%.*s] has no right to remove other users [%.*s]!\n",
					src->user.len, src->user.s,	uri.len, uri.s);
			goto error;
	}

	/* verify if the user that is to be removed is a member of the room */
	member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
	if(member== NULL)
	{
		LM_ERR("user [%.*s] is not member of room [%.*s]!\n", 
				inv_uri.user.len, inv_uri.user.s, room_name.len, room_name.s);
		goto error;
	}
				
	if(member->flags & IMC_MEMBER_OWNER)
	{
		LM_ERR("user [%.*s] is owner of room [%.*s]"
			" -- cannot be removed!\n", inv_uri.user.len, inv_uri.user.s,
			room_name.len, room_name.s);
		goto error;
	}	

	/* send message to the removed person */
	body.s = "You have been removed from this room";
	body.len = strlen(body.s);

	LM_DBG("to: [%.*s]\nfrom: [%.*s]\nbody: [%.*s]\n",
			member->uri.len, member->uri.s , room->uri.len, room->uri.s,
			body.len, body.s);
	imc_send_message(&room->uri, &member->uri, &imc_hdr_ctype, &body);

	member->flags |= IMC_MEMBER_DELETED;
	imc_del_member(room, &inv_uri.user, &inv_uri.host);

	body.s = imc_body_buf;
	body.len = snprintf(body.s, IMC_BUF_SIZE, "*** [%.*s] (%.*s) has been removed from the room",
					member->uri.len, member->uri.s, member->fullname.len, member->fullname.s);
	if(body.len>0)
		imc_room_broadcast(room, &imc_hdr_ctype, &body);


	if(uri.s!=0)
		pkg_free(uri.s);
	imc_release_room(room);
	return 0;

error:
	if(uri.s!=0)
		pkg_free(uri.s);
	if(room!=NULL)
		imc_release_room(room);
	return -1;
}
Esempio n. 20
0
static void ietf_get_rules(subs_t* subs, xmlDocPtr xcap_tree, xcap_rule_t **rules)
{
	str w_uri= {0, 0};
	char* id = NULL, *domain = NULL, *time_cont= NULL;
	int apply_rule = -1;
	xmlNodePtr ruleset_node = NULL, node1= NULL, node2= NULL;
	xmlNodePtr cond_node = NULL, except_node = NULL;
	xmlNodePtr identity_node = NULL, sphere_node = NULL;
	xmlNodePtr iden_child;
	xmlNodePtr validity_node, time_node;
	time_t t_init, t_fin, t;
	int valid= 0;
	xcap_rule_t *rule = NULL;

        *rules = NULL;

	uandd_to_uri(subs->from_user, subs->from_domain, &w_uri);
	if(w_uri.s == NULL)
	{
		LM_ERR("while creating uri\n");
		return;
	}
	ruleset_node = xmlDocGetNodeByName(xcap_tree, "ruleset", NULL);
	if(ruleset_node == NULL)
	{
		LM_DBG("ruleset_node NULL\n");
		goto error;

	}
	for(node1 = ruleset_node->children ; node1; node1 = node1->next)
	{
		if(xmlStrcasecmp(node1->name, (unsigned char*)"text")==0 )
				continue;

		/* process conditions */
		LM_DBG("node1->name= %s\n", node1->name);

		cond_node = xmlNodeGetChildByName(node1, "conditions");
		if(cond_node == NULL)
		{
			LM_DBG("cond node NULL\n");
			goto error;
		}
		LM_DBG("cond_node->name= %s\n", cond_node->name);

		validity_node = xmlNodeGetChildByName(cond_node, "validity");
		if(validity_node !=NULL)
		{
			LM_DBG("found validity tag\n");

			t= time(NULL);

			/* search all from-until pair */
			for(time_node= validity_node->children; time_node;
					time_node= time_node->next)
			{
				if(xmlStrcasecmp(time_node->name, (unsigned char*)"from")!= 0)
				{
					continue;
				}
				time_cont= (char*)xmlNodeGetContent(time_node);
				t_init= xml_parse_dateTime(time_cont);
				xmlFree(time_cont);
				if(t_init< 0)
				{
					LM_ERR("failed to parse xml dateTime\n");
					goto error;
				}

				if(t< t_init)
				{
					LM_DBG("the lower time limit is not respected\n");
					continue;
				}

				time_node= time_node->next;
				while(1)
				{
					if(time_node== NULL)
					{
						LM_ERR("bad formatted xml doc:until child not found in"
								" validity pair\n");
						goto error;
					}
					if( xmlStrcasecmp(time_node->name,
								(unsigned char*)"until")== 0)
						break;
					time_node= time_node->next;
				}

				time_cont= (char*)xmlNodeGetContent(time_node);
				t_fin= xml_parse_dateTime(time_cont);
				xmlFree(time_cont);

				if(t_fin< 0)
				{
					LM_ERR("failed to parse xml dateTime\n");
					goto error;
				}

				if(t <= t_fin)
				{
					LM_DBG("the rule is active at this time\n");
					valid= 1;
				}

			}

			if(!valid)
			{
				LM_DBG("the rule is not active at this time\n");
				continue;
			}

		}

		sphere_node = xmlNodeGetChildByName(cond_node, "sphere");
		if(sphere_node!= NULL)
		{
			/* check to see if matches presentity current sphere */
			/* ask presence for sphere information */

			char* sphere= pres_get_sphere(&subs->pres_uri);
			if(sphere)
			{
				char* attr= (char*)xmlNodeGetContent(sphere_node);
				if(xmlStrcasecmp((unsigned char*)attr, (unsigned char*)sphere)!= 0)
				{
					LM_DBG("sphere condition not respected\n");
					pkg_free(sphere);
					xmlFree(attr);
					continue;
				}
				pkg_free(sphere);
				xmlFree(attr);

			}
			else
			{
				LM_DBG("Noo sphere definition found\n");
				continue;
			}
			/* if the user has not define a sphere
			 *						consider the condition false*/
		}

		identity_node = xmlNodeGetChildByName(cond_node, "identity");
		if(identity_node == NULL)
		{
			LM_ERR("didn't find identity tag\n");
			goto error;
		}

		iden_child= xmlNodeGetChildByName(identity_node, "one");
		if(iden_child)
		{
			for(node2 = identity_node->children; node2; node2 = node2->next)
			{
				if(xmlStrcasecmp(node2->name, (unsigned char*)"one")!= 0)
					continue;

				id = xmlNodeGetAttrContentByName(node2, "id");
				if(id== NULL)
				{
					LM_ERR("while extracting attribute\n");
					goto error;
				}
				if((strlen(id)== w_uri.len &&
							(strncmp(id, w_uri.s, w_uri.len)==0)))
				{
					apply_rule = 1;
					xmlFree(id);
					break;
				}
				xmlFree(id);
			}
		}

		/* search for many node*/
		iden_child= xmlNodeGetChildByName(identity_node, "many");
		if(iden_child)
		{
			domain = NULL;
			for(node2 = identity_node->children; node2; node2 = node2->next)
			{
				if(xmlStrcasecmp(node2->name, (unsigned char*)"many")!= 0)
					continue;

				domain = xmlNodeGetAttrContentByName(node2, "domain");
				if(domain == NULL)
				{
					LM_DBG("No domain attribute to many\n");
				}
				else
				{
					LM_DBG("<many domain= %s>\n", domain);
					if((strlen(domain)!= subs->from_domain.len &&
								strncmp(domain, subs->from_domain.s,
									subs->from_domain.len) ))
					{
						xmlFree(domain);
						continue;
					}
				}
				xmlFree(domain);
				apply_rule = 1;
				if(node2->children == NULL)       /* there is no exception */
					break;

				for(except_node = node2->children; except_node;
						except_node= except_node->next)
				{
					if(xmlStrcasecmp(except_node->name, (unsigned char*)"except"))
						continue;

					id = xmlNodeGetAttrContentByName(except_node, "id");
					if(id!=NULL)
					{
						if((strlen(id)- 1== w_uri.len &&
								(strncmp(id, w_uri.s, w_uri.len)==0)))
						{
							xmlFree(id);
							apply_rule = 0;
							break;
						}
						xmlFree(id);
					}
					else
					{
						domain = NULL;
						domain = xmlNodeGetAttrContentByName(except_node, "domain");
						if(domain!=NULL)
						{
							LM_DBG("Found except domain= %s\n- strlen(domain)= %d\n",
									domain, (int)strlen(domain));
							if(strlen(domain)==subs->from_domain.len &&
								(strncmp(domain,subs->from_domain.s , subs->from_domain.len)==0))
							{
								LM_DBG("except domain match\n");
								xmlFree(domain);
								apply_rule = 0;
								break;
							}
							xmlFree(domain);
						}

					}
				}
				if(apply_rule== 1)  /* if a match was found no need to keep searching*/
					break;

			}
		}
		if(apply_rule ==1)
			break;
	}

	LM_DBG("apply_rule= %d\n", apply_rule);
	if(w_uri.s!=NULL)
		pkg_free(w_uri.s);

	if( !apply_rule || !node1)
		return;

	rule = (xcap_rule_t *)pkg_malloc(sizeof(*rule));
	if (rule == NULL)
	{
		LM_ERR("cannot allocate pkg_mem\n");
		return;
	}

	/* TODO: in IETF mode only the first matching rule is returned */
	rule->node = node1;
	rule->next = NULL;
	*rules = rule;

	return;
error:
	if(w_uri.s)
		pkg_free(w_uri.s);
}
Esempio n. 21
0
int Sipreply2Xmpp(ua_pres_t* hentity, struct sip_msg * msg)
{
	char* uri;
	/* named according to the direction of the message in xmpp*/
	str from_uri;
	str to_uri;
	xmlDocPtr doc= NULL;
	xmlNodePtr root_node= NULL, node = NULL;
	xmlAttrPtr attr= NULL;
	str xmpp_msg;
	int code;
	str reason;
	char* err_reason= NULL;
	xmlBufferPtr buffer= NULL;

	LM_DBG("start..\n");
	uri=(char*)pkg_malloc(sizeof(char)*( hentity->watcher_uri->len+1));
	if(uri== NULL)
	{
		LM_ERR("no more memory\n");
		goto error;
	}
	memcpy(uri, hentity->watcher_uri->s, hentity->watcher_uri->len);
	uri[hentity->watcher_uri->len]= '\0';
	to_uri.s= duri_sip_xmpp(uri);
	if(to_uri.s== NULL)
	{
		LM_ERR("whil decoding sip uri in xmpp\n");
		pkg_free(uri);
		goto error;
	}

	to_uri.len= strlen(to_uri.s);
	pkg_free(uri);

	uri=(char*)pkg_malloc(sizeof(char)*( hentity->pres_uri->len+1));
	if(uri== NULL)
	{
		LM_ERR("no more memory\n");
		goto error;
	}
	memcpy(uri, hentity->pres_uri->s, hentity->pres_uri->len);
	uri[hentity->pres_uri->len]= '\0';
	from_uri.s= euri_sip_xmpp(uri);
	if(from_uri.s== NULL)
	{
		LM_ERR("while encoding sip uri in xmpp\n");
		pkg_free(uri);
		goto error;
	}

	from_uri.len= strlen(from_uri.s);
	pkg_free(uri);

	doc= xmlNewDoc(BAD_CAST "1.0");
	if(doc==0)
		goto error;
	root_node = xmlNewNode(NULL, BAD_CAST "presence");

	if(root_node==0)
		goto error;
	xmlDocSetRootElement(doc, root_node);

	attr= xmlNewProp(root_node, BAD_CAST "to", BAD_CAST to_uri.s);
	if(attr== NULL)
	{
		LM_ERR("while adding attribute to\n");
		goto error;
	}
	attr= xmlNewProp(root_node, BAD_CAST "from", BAD_CAST from_uri.s);
	if(attr== NULL)
	{
		LM_ERR("while adding attribute from\n");
		goto error;
	}

	if(msg== FAKED_REPLY)
	{
		code = 408;
		reason.s= "Request Timeout";
		reason.len= strlen(reason.s)- 1;
	}
	else
	{
		code= msg->first_line.u.reply.statuscode;
		reason= msg->first_line.u.reply.reason;
	}

	LM_DBG(" to_uri= %s\n\t from_uri= %s\n",
			to_uri.s, from_uri.s);

	if(code>=300)
	{
		LM_DBG(" error code(>= 300)\n");
		err_reason= get_error_reason(code, &reason);
		if(err_reason== NULL)
		{
			LM_ERR("couldn't get response phrase\n");
			goto error;
		}

		attr= xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "error");
		if(attr== NULL)
		{
			LM_ERR("while adding new attribute\n");
			goto error;
		}
		node= xmlNewChild(root_node, 0, BAD_CAST  "error", 0 );
		if(node== NULL)
		{
			LM_ERR("while adding new node\n");
			goto error;
		}
		node= xmlNewChild(node, 0,  BAD_CAST err_reason, 0 );
		if(node== NULL)
		{
			LM_ERR("while adding new node\n");
			goto error;
		}

		attr= xmlNewProp(node, BAD_CAST "xmlns",
				BAD_CAST "urn:ietf:params:xml:ns:xmpp-stanzas");
		if(attr== NULL)
		{
			LM_ERR("while adding new attribute\n");
			goto error;
		}

	} else {
		if(code>=200 )
		{
			LM_DBG(" 2xx code\n");
			attr= xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "subscribed");
			if(attr== NULL)
			{
				LM_ERR("while adding new attribute\n");
				goto error;
			}
		}
	}

	buffer= xmlBufferCreate();
	if(buffer== NULL)
	{
		LM_ERR("while adding creating new buffer\n");
		goto error;
	}

	xmpp_msg.len= xmlNodeDump(buffer, doc, root_node, 1,1);
	if(xmpp_msg.len== -1)
	{
		LM_ERR("while dumping node\n");
		goto error;
	}
	xmpp_msg.s= (char*)xmlBufferContent( buffer);
	if(xmpp_msg.s==  NULL)
	{
		LM_ERR("while extracting buffer content\n");
		goto error;
	}


	LM_DBG("xmpp_msg: %.*s\n",xmpp_msg.len, xmpp_msg.s);

	if(xmpp_packet(&from_uri, &to_uri, &xmpp_msg, &hentity->to_tag)< 0)
	{
		LM_ERR("while sending xmpp_reply_to_subscribe\n");
		goto error;
	}
	if(err_reason)
		pkg_free(err_reason);
	xmlFreeDoc(doc);

	return 0;

error:

	if(doc)
		xmlFreeDoc(doc);
	if(err_reason)
		pkg_free(err_reason);
	return -1;

}
Esempio n. 22
0
static void oma_get_rules(subs_t* subs, xmlDocPtr xcap_tree, xcap_rule_t **rules)
{
	int apply_rule = 0, current_node_type = -1;
	str w_uri = {0, 0};
	xmlNodePtr ruleset_node = NULL, cond_node = NULL;
	xmlNodePtr node1 = NULL, node2 = NULL, current_node = NULL;
	xcap_rule_t *tmp_rule = NULL;
	xcap_rule_t *identity_rules = NULL, *external_rules = NULL, *anonymous_rules = NULL, *other_identity_rules = NULL;
	xcap_rule_t *identity_tail = NULL, *external_tail = NULL, *anonymous_tail = NULL, *other_identity_tail = NULL;

        *rules = NULL;

	uandd_to_uri(subs->from_user, subs->from_domain, &w_uri);
	if(w_uri.s == NULL)
	{
		LM_ERR("while creating uri\n");
		return;
	}

	ruleset_node = xmlDocGetNodeByName(xcap_tree, "ruleset", NULL);
	if(ruleset_node == NULL)
	{
		LM_ERR("ruleset_node not found\n");
		pkg_free(w_uri.s);
	        return;
	}

	for(node1 = ruleset_node->children; node1; node1 = node1->next)
	{
		if(xmlStrcasecmp(node1->name, (unsigned char*)"text")==0)
		        continue;

		cond_node = xmlNodeGetChildByName(node1, "conditions");
		if(cond_node == NULL)
		{
			LM_WARN("condition node not found\n");
			continue;
		}

                apply_rule = 0;
                current_node = node1;
                current_node_type = -1;

                for(node2 = cond_node->children; node2; node2 = node2->next)
                {
                        if(xmlStrcasecmp(node2->name, (unsigned char*)"identity") == 0)
                        {
                                current_node_type = IDENTITY_RULE;
                                apply_rule = oma_match_identity_condition(node2, subs, &w_uri);
                                break;
                        }
                        else if(xmlStrcasecmp(node2->name, (unsigned char*)"external-list") == 0)
                        {
                                current_node_type = EXTERNAL_LIST_RULE;
                                apply_rule = oma_match_external_list_condition(node2, subs, &w_uri);
                                break;
                        }
                        else if(xmlStrcasecmp(node2->name, (unsigned char*)"anonymous-request") == 0)
                        {
                                current_node_type = ANONYMOUS_REQUEST_RULE;
                                apply_rule = oma_match_anonymous_condition(node2, subs, &w_uri);
                                break;
                        }
                        else if(xmlStrcasecmp(node2->name, (unsigned char*)"other-identity") == 0)
                        {
                                current_node_type = OTHER_IDENTITY_RULE;
                                apply_rule = 1;
                                break;
                        }
                        else
                        {
                                /* unknown condition */
                                continue;
                        }

                }

                /* finished scanning all conditions for a given rule */
                if (apply_rule)
                {
                        tmp_rule = (xcap_rule_t *)pkg_malloc(sizeof(*tmp_rule));
                        if (tmp_rule == NULL)
                        {
                                LM_ERR("pkg mem\n");
                                goto error;
                        }
                        tmp_rule->node = current_node;
                        tmp_rule->next = NULL;
                        switch (current_node_type)
                        {
                                case IDENTITY_RULE:
                                        if(identity_rules == NULL)
                                                identity_rules = tmp_rule;
                                        else
                                                identity_tail->next = tmp_rule;
                                        identity_tail = tmp_rule;
                                        break;
                                case EXTERNAL_LIST_RULE:
                                        if(external_rules == NULL)
                                                external_rules = tmp_rule;
                                        else
                                                external_tail->next = tmp_rule;
                                        external_tail = tmp_rule;
                                        break;
                                case ANONYMOUS_REQUEST_RULE:
                                        if(anonymous_rules == NULL)
                                                anonymous_rules = tmp_rule;
                                        else
                                                anonymous_tail->next = tmp_rule;
                                        anonymous_tail = tmp_rule;
                                        break;
                                case OTHER_IDENTITY_RULE:
                                        if(other_identity_rules == NULL)
                                                other_identity_rules = tmp_rule;
                                        else
                                                other_identity_tail->next = tmp_rule;
                                        other_identity_tail = tmp_rule;
                                        break;
                                default:
                                        /* this will never happen */
                                        break;
                        }
                }
	}

        if (anonymous_rules)
        {
                *rules = anonymous_rules;
                free_rules(identity_rules);
                free_rules(external_rules);
                free_rules(other_identity_rules);
        }
        else if (identity_rules)
        {
                *rules = identity_rules;
                free_rules(external_rules);
                free_rules(anonymous_rules);
                free_rules(other_identity_rules);
        }
        else if (external_rules)
        {
                *rules = external_rules;
                free_rules(identity_rules);
                free_rules(anonymous_rules);
                free_rules(other_identity_rules);
        }
        else if (other_identity_rules)
        {
                *rules = other_identity_rules;
                free_rules(identity_rules);
                free_rules(external_rules);
                free_rules(anonymous_rules);
        }
        else
        {
                *rules = NULL;
                LM_DBG("no matching rules found\n");
        }

        pkg_free(w_uri.s);
        return;

error:
        if (w_uri.s)
                pkg_free(w_uri.s);
        free_rules(identity_rules);
        free_rules(external_rules);
        free_rules(anonymous_rules);
        free_rules(other_identity_rules);
}
Esempio n. 23
0
/**
 * Force Service routes (upon request)
 */
int force_service_routes(struct sip_msg* _m, udomain_t* _d) {
	struct hdr_field *it;
	int i;
	str new_route_header;
	struct lump* lmp = NULL;
	char * buf;
	pcontact_t * c = getContactP(_m, _d);
	
	// Contact not found => not following service-routes
	if (c == NULL) return -1;

	/* we need to be sure we have seen all HFs */
	parse_headers(_m, HDR_EOH_F, 0);

	/* Savbe current buffer */
	buf = _m->buf;

	// Delete old Route headers:
	if (_m->route) {
		for (it = _m->route; it; it = it->next) {
			if (it->type == HDR_ROUTE_T) {
				if ((lmp = del_lump(_m, it->name.s - buf, it->len, HDR_ROUTE_T)) == 0) {
					LM_ERR("del_lump failed \n");
					return -1;
				}
			}
		}
	}

	/* Reset dst_uri if previously set either by loose route or manually */
	if (_m->dst_uri.s && _m->dst_uri.len) {
		pkg_free(_m->dst_uri.s);
		_m->dst_uri.s = NULL;
		_m->dst_uri.len = 0;
	}

	/* Lock this record while working with the data: */
	ul.lock_udomain(_d, &c->aor);

	if (c->num_service_routes > 0) {
		/* Create anchor for new Route-Header: */
		lmp = anchor_lump(_m, _m->headers->name.s - buf,0,0);
		if (lmp == 0) {
			LM_ERR("Failed to get anchor lump\n");
			goto error;
		}	
		/* Calculate the length: */
		new_route_header.len = route_start.len + route_end.len + (c->num_service_routes-1) * route_sep.len;
		for(i=0; i< c->num_service_routes; i++)
			new_route_header.len+=c->service_routes[i].len;		
		/* Allocate the memory for this new header: */
		new_route_header.s = pkg_malloc(new_route_header.len);
		if (!new_route_header.s) {
			LM_ERR("Error allocating %d bytes\n", new_route_header.len);
			goto error;
		}
		
		/* Construct new header */
		new_route_header.len = 0;
		STR_APPEND(new_route_header, route_start);
		for(i=0; i < c->num_service_routes; i++) {
			if (i) STR_APPEND(new_route_header, route_sep);
			STR_APPEND(new_route_header, c->service_routes[i]);
		}
		STR_APPEND(new_route_header, route_end);

		LM_DBG("Setting route header to <%.*s> \n", new_route_header.len, new_route_header.s);

		if ((lmp = insert_new_lump_after(lmp, new_route_header.s, new_route_header.len, HDR_ROUTE_T)) == 0) {
			LM_ERR("Error inserting new route set\n");
			pkg_free(new_route_header.s);
			goto error;
		}

		LM_DBG("Setting dst_uri to <%.*s> \n", c->service_routes[0].len,
			c->service_routes[i].s);

		if (set_dst_uri(_m, &c->service_routes[0]) !=0 ) {
			LM_ERR("Error setting new dst uri\n");
			goto error;
		}
	}
	/* Unlock domain */
	ul.unlock_udomain(_d, &c->aor);
	return 1;
error:
	/* Unlock domain */
	ul.unlock_udomain(_d, &c->aor);
	return -1;
	
}
int r_send_third_party_reg(r_third_party_registration *r, int expires) {
	str h = { 0, 0 };
	str b = { 0, 0 };
	uac_req_t req;

	LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n",
			r->req_uri.len, r->req_uri.s);

	h.len = event_hdr.len + max_fwds_hdr.len;
	h.len += expires_s.len + 12 + expires_e.len;

	h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len;

	if (r->pvni.len)
		h.len += p_visited_network_id_s.len + p_visited_network_id_e.len
				+ r->pvni.len;

	if (r->pani.len)
		h.len += p_access_network_info_s.len + p_access_network_info_e.len
				+ r->pani.len;

	if (r->cv.len)
		h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len;

	h.s = pkg_malloc(h.len);
	if (!h.s) {
		LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len);
		h.len = 0;
		return 0;
	}

	h.len = 0;
	STR_APPEND(h, event_hdr);

	STR_APPEND(h, max_fwds_hdr);

	STR_APPEND(h, expires_s);
	sprintf(h.s + h.len, "%d", expires);
	h.len += strlen(h.s + h.len);
	STR_APPEND(h, expires_e);

	STR_APPEND(h, contact_s);
	STR_APPEND(h, isc_my_uri_sip);
	STR_APPEND(h, contact_e);

	if (r->pvni.len) {
		STR_APPEND(h, p_visited_network_id_s);
		STR_APPEND(h, r->pvni);
		STR_APPEND(h, p_visited_network_id_e);
	}

	if (r->pani.len) {
		STR_APPEND(h, p_access_network_info_s);
		STR_APPEND(h, r->pani);
		STR_APPEND(h, p_access_network_info_e);
	}

	if (r->cv.len) {
		STR_APPEND(h, p_charging_vector_s);
		STR_APPEND(h, r->cv);
		STR_APPEND(h, p_charging_vector_e);
	}
	LM_CRIT("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s);
	if (r->service_info.len) {
		b.len = body_s.len + r->service_info.len + body_e.len;
		b.s = pkg_malloc(b.len);
		if (!b.s) {
			LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
			b.len = 0;
			return 0;
		}

		b.len = 0;
		STR_APPEND(b, body_s);
		STR_APPEND(b, r->service_info);
		STR_APPEND(b, body_e);
	}

	set_uac_req(&req, &method, &h, &b, 0,
			TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED,
			r_third_party_reg_response, &(r->req_uri));
	if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) {
		LM_ERR("r_send_third_party_reg: Error sending in transaction\n");
		goto error;
	}
	if (h.s)
		pkg_free(h.s);
	return 1;

	error: if (h.s)
		pkg_free(h.s);
	return 0;
}