Exemplo n.º 1
0
static void set_output_pv_params(struct sip_msg *msg, str *body_in, pv_spec_p body_pv, str *ctype_in,
								 pv_spec_p ctype_pv, CURL *handle, pv_spec_p code_pv)
{
	pv_value_t val;
	long http_rc;
	CURLcode rc;

	val.flags = PV_VAL_STR;
	val.rs = *body_in;

	if (pv_set_value(msg, (pv_spec_p)body_pv, 0, &val) != 0)
		LM_ERR("failed to set output body pv\n");

	if (ctype_pv) {
		val.rs = *ctype_in;
		if (pv_set_value(msg, (pv_spec_p)ctype_pv, 0, &val) != 0)
			LM_ERR("failed to set output ctype pv\n");
	}

	if (code_pv) {
		rc = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_rc);
		if (rc != CURLE_OK)
			LM_ERR("curl_easy_getinfo: %s\n", curl_easy_strerror(rc));

		LM_DBG("Last response code: %ld\n", http_rc);

		val.flags = PV_VAL_INT|PV_TYPE_INT;
		val.ri = (int)http_rc;
		if (pv_set_value(msg, (pv_spec_p)code_pv, 0, &val) != 0)
			LM_ERR("failed to set output code pv\n");
	}
}
Exemplo n.º 2
0
static int dp_update(struct sip_msg * msg, pv_spec_t * src, pv_spec_t * dest,
											str * repl, str * attrs)
{
	pv_value_t val;

	if (repl->s && repl->len) {
		val.flags = PV_VAL_STR;
		val.rs = *repl;
		if (pv_set_value( msg, dest, 0, &val)!=0) {
			LM_ERR("falied to set the output value!\n");
			return -1;
		}
	}

	if(!attr_pvar)
		return 0;

	val.flags = PV_VAL_STR;
	val.rs = *attrs;
	if (pv_set_value( msg, attr_pvar, 0, &val)!=0) {
		LM_ERR("falied to set the attr value!\n");
		return -1;
	}

	return 0;
}
Exemplo n.º 3
0
static int read_and_write2var(struct sip_msg* msg, FILE** strm, gparam_p outvar)
{
	#define MAX_LINE_SIZE 1024
	#define MAX_BUF_SIZE 32 * MAX_LINE_SIZE

	int buflen=0, tmplen;
	pv_value_t outval;
	char buf[MAX_BUF_SIZE], tmpbuf[MAX_LINE_SIZE];


	while((tmplen=fread(tmpbuf, 1, MAX_LINE_SIZE, *strm))) {
		if ((buflen + tmplen) >= MAX_BUF_SIZE) {
			LM_WARN("no more space in output buffer\n");
			break;
		}
		memcpy(buf+buflen, tmpbuf, tmplen);
		buflen += tmplen;
	}

	outval.flags = PV_VAL_STR;
	outval.rs.s = buf;
	outval.rs.len = buflen;

	if (buflen &&
		pv_set_value(msg, &outvar->v.pve->spec, 0, &outval) < 0) {
		LM_ERR("cannot set output pv value\n");
		return -1;
	}

	return 0;

	#undef MAX_LINE_SIZE
	#undef MAX_BUF_SIZE
}
Exemplo n.º 4
0
/**
 * Function that runs a JSON-RPC request
 * Returns:
 *  -1: internal error
 *  -2: communication error
 *  -3: reply error
 *   1: success
 */
static int jrpc_request(struct sip_msg *msg, union sockaddr_union *dst,
				str *method, str *params, pv_spec_p spec)
{
	int id, ret;
	char *cmd;
	pv_value_t val;

	id = jsonrpc_unique_id();
	cmd = jsonrpc_build_cmd(method, params, &id);
	if (!cmd) {
		LM_ERR("cannot build jsonrpc command \n");
		return -1;
	}

	ret = jsonrpc_handle_cmd(dst, cmd, &id, &val);
	cJSON_PurgeString(cmd);
	if (ret == -2) {
		LM_ERR("communication error with %s:%hu\n", JSONRPC_PRINT(dst));
		return ret;
	}

	if (pv_set_value(msg, spec, 0, &val) < 0) {
		LM_ERR("cannot set returned value!\n");
		ret = -1;
	}
	/* XXX: free the value returned */
	if ((val.flags & PV_VAL_STR) && !(val.flags & PV_VAL_INT))
		cJSON_PurgeString(val.rs.s);

	return ret;
}
Exemplo n.º 5
0
static int pv_set_count(struct sip_msg* msg, pv_spec_t *pv_name, pv_spec_t *pv_result)
{
	pv_value_t pv_val;

	memset(&pv_val, 0, sizeof(pv_value_t));

	pv_name->pvp.pvi.type = PV_IDX_INT;
	pv_name->pvp.pvi.u.ival = 0;

	while(pv_val.flags != PV_VAL_NULL)
	{
		if(pv_get_spec_value(msg, pv_name, &pv_val) < 0)
		{
			LM_ERR("PV get function failed\n");
			return -1;
		}
		pv_name->pvp.pvi.u.ival++;
	}

	pv_val.flags = PV_TYPE_INT;
	pv_val.ri = pv_name->pvp.pvi.u.ival-1;

	if (pv_set_value( msg, pv_result, 0, &pv_val) != 0)
	{
		LM_ERR("SET output value failed.\n");
		return -1;
	}

	LM_DBG("Set count = %d\n", pv_val.ri);
	return 1;
}
Exemplo n.º 6
0
int cmd_send_req(struct sip_msg *msg, int *cluster_id, int *node_id,
								str *gen_msg, pv_spec_t *param_tag)
{
	pv_value_t tag_val;
	int rc;

	/* generate tag */
	generate_msg_tag(&tag_val, *cluster_id);

	if (param_tag && pv_set_value(msg, param_tag, 0, &tag_val) < 0) {
		LM_ERR("Unable to set tag pvar\n");
		return -1;
	}

	rc = send_gen_msg(*cluster_id, *node_id, gen_msg, &tag_val.rs, 1);
	switch (rc) {
		case 0:
			return 1;
		case 1:
			return -1;
		case -1:
			return -2;
		case -2:
			return -3;
		default:
			return -3;
	}
}
Exemplo n.º 7
0
static int ts_usec_delta(struct sip_msg *msg, int *t1s,
		int *t1u, int *t2s, int *t2u, pv_spec_t *_res)
{
	pv_value_t res;

	res.ri = abs(1000000 * (*t1s - *t2s) + *t1u - *t2u);
	res.flags = PV_TYPE_INT;

	if (pv_set_value(msg, _res, 0, &res)) {
		LM_ERR("cannot store result value\n");
		return -1;
	}
	return 1;
}
Exemplo n.º 8
0
static int scriptroute_add_param(struct sip_msg *msg,
								 struct scriptroute_params *param) {

	int index;
	evi_param_t *it = parameters->first;
	pv_value_t val;

	if (param->index) {
		/* search the parameter by it's index */
		for (index = 1; it && index != param->index; it = it->next, index++);
		if (!it) {
			LM_WARN("Parameter %d not found - max %d\n", param->index, index);
			return 0;
		}
	} else {
		/* specified by name */
		for (; it; it = it->next) {
			if (it->name.s && it->name.len == param->name.len &&
					memcmp(it->name.s, param->name.s, it->name.len) == 0)
				break;
		}
		if (!it) {
			LM_WARN("Parameter <%.*s> not found for event <%.*s>\n",
					param->name.len, param->name.s,
					event_name->len, event_name->s);
			return 0;
		}
	}

	/* parameter found - populate it */
	if (it->flags & EVI_INT_VAL) {
		val.ri = it->val.n;
		val.flags = PV_VAL_INT|PV_TYPE_INT;
	} else {
		val.rs.len = it->val.s.len;
		val.rs.s = it->val.s.s;
		val.flags = PV_VAL_STR;
	}

	if (pv_set_value(msg, &param->spec, 0, &val) < 0) {
		LM_WARN("cannot populate parameter\n");
		return 0;
	}

	return 1;
}
Exemplo n.º 9
0
int cmd_send_req(struct sip_msg *msg, char *param_cluster, char *param_node,
								char *param_msg, char *param_tag)
{
	int cluster_id, node_id;
	str gen_msg;
	pv_value_t tag_val;
	int rc;

	if (fixup_get_ivalue(msg, (gparam_p)param_cluster, &cluster_id) < 0) {
		LM_ERR("Failed to fetch cluster id parameter\n");
		return -1;
	}
	if (fixup_get_ivalue(msg, (gparam_p)param_node, &node_id) < 0) {
		LM_ERR("Failed to fetch node id parameter\n");
		return -1;
	}

	if (fixup_get_svalue(msg, (gparam_p)param_msg, &gen_msg) < 0) {
		LM_ERR("Failed to fetch message parameter\n");
		return -1;
	}

	/* generate tag */
	generate_msg_tag(&tag_val, cluster_id);

	if (param_tag && pv_set_value(msg, (pv_spec_p)param_tag, 0, &tag_val) < 0) {
		LM_ERR("Unable to set tag pvar\n");
		return -1;
	}

	rc = send_gen_msg(cluster_id, node_id, &gen_msg, &tag_val.rs, 1);
	switch (rc) {
		case 0:
			return 1;
		case 1:
			return -1;
		case -1:
			return -2;
		case -2:
			return -3;
		default:
			return -3;
	}
}
Exemplo n.º 10
0
static int l_siplua_pseudoVarSet(lua_State *L)
{
  struct sipapi_object *o;
  const char *name;
  str s;
  pv_spec_t dspec;
  pv_value_t val;
  int retval;

  o = luaL_checkudata(L, 1, "siplua.api");
  name = luaL_checkstring(L, 2);
  if (*name == '$')
    ++name;
  s.s = (char *)name;
  s.len = strlen(name);
  if (!pv_parse_spec(&s, &dspec))
	  return luaL_error(L, "error in parsing pvar `%s'", name);
  if (!pv_is_w(&dspec))
    return luaL_error(L, "read only PV in left expression");
  luaL_checkany(L, 3);
  if (lua_type(L, 3) == LUA_TNIL)
    {
      val.flags = PV_VAL_NULL;
    }
  else if (lua_type(L, 3) == LUA_TNUMBER)
    {
      val.ri = luaL_checkinteger(L, 3);
      val.flags = PV_VAL_INT;
    }
  else
    {
      val.rs.s = (char *)luaL_checkstring(L, 3);
      val.rs.len = strlen(val.rs.s);
      val.flags = PV_VAL_STR;
    }
/*   siplua_log(L_ALERT, "dspec.setf(, , EQ_T, %.*s)", val.rs.len, val.rs.s); */
  retval = pv_set_value(o->msg, &dspec, EQ_T, &val);
  if (retval >= 0)
    lua_pushboolean(L, 1);
  else
    lua_pushnil(L);
  return 1;
}
Exemplo n.º 11
0
inline int set_alias_to_pvar(struct sip_msg* _msg, str *alias, int no, void *p)
{
	pv_value_t val;
	pv_spec_t *pvs=(pv_spec_t*)p;

	if(no && !ald_append_branches)
		return 0;

	/* set the PVAR */
	val.flags = PV_VAL_STR;
	val.ri = 0;
	val.rs = *alias;

	if(pv_set_value(_msg, pvs, (int)(no?EQ_T:COLONEQ_T), &val)<0) {
		LM_ERR("setting PV AVP failed\n");
		return -1;
	}
	return 0;
}
Exemplo n.º 12
0
/**
 * Set the dialog's AVP value so the dialog module will use this value
 * and not the default when returning from the dialog callback.
 *
 * @param msg The current message to bind the AVP to.
 * @param value The value you want to set the AVP to.
 *
 * @return 0 on success, -1 on an error.
 */
static int set_timeout_avp(struct sip_msg *msg, unsigned int value)
{
	int rtn = -1; /* assume failure */
	pv_value_t pv_val;
	int result = 0;

	/* Set the dialog timeout HERE */
	if (timeout_avp) {
		if ((result = pv_get_spec_value(msg, timeout_avp, &pv_val)) == 0) {
			/* We now hold a reference to the AVP */
			if (pv_val.flags & PV_VAL_INT && pv_val.ri == value) {
				/* INT AVP with the same value */
				LM_DBG("Current timeout value already set to %d\n",
					value);
				rtn = 0;
			} else {
				/* AVP not found or non-INT value -> add a new one*/
				pv_val.flags = PV_VAL_INT|PV_TYPE_INT;
				pv_val.ri = value;
				if (pv_set_value(msg,timeout_avp,EQ_T,&pv_val)!=0) {
					LM_ERR("failed to set new dialog timeout value\n");
				} else {
					LM_DBG("set dialog timeout value to %d\n", value);
					rtn = 0;
				}
			}
		}
		else {
			LM_ERR("SST not reset. get avp result is %d\n", result);
		}
	}
	else {
		LM_ERR("SST needs to know the name of the dialog timeout AVP!\n");
	}
	return(rtn);
}
Exemplo n.º 13
0
int get_source_group(struct sip_msg* msg, char *arg) {
	int group = -1;
	struct in_addr in;
	struct ip_addr *ip;
	str str_ip, partition;
	pv_value_t pvt;
	struct part_pvar *ppv;
	struct pm_part_struct *ps;

	ppv  = (struct part_pvar *)arg;

	if (ppv->part) {
		if (fixup_get_svalue(msg, ppv->part, &partition)) {
			    LM_ERR("cannot get partition value\n");
				return -1;
		}

		str_trim_spaces_lr(partition);
		ps = get_part_struct(&partition);

		if (ps == NULL) {
			LM_ERR("no such partition (%.*s)\n", partition.len, partition.s);
			return -1;
		}

	} else {
		ps = get_part_struct(&def_part);
		if (ps == NULL) {
			LM_ERR("no default partition\n");
			return -1;
		}
	}

	LM_DBG("Looking for <%x, %u> in address table\n",
			msg->rcv.src_ip.u.addr32[0], msg->rcv.src_port);

	in.s_addr = msg->rcv.src_ip.u.addr32[0];
	str_ip.s = inet_ntoa(in);
	str_ip.len = str_ip.s ? strlen(str_ip.s) : 0;

	ip = str2ip(&str_ip);

	group = find_group_in_hash_table(*ps->hash_table,
				ip,
				msg->rcv.src_port);
	group=0;

	LM_DBG("Found <%d>\n", group);

	if (group == -1) {

		LM_DBG("Looking for <%x, %u> in subnet table\n",
			msg->rcv.src_ip.u.addr32[0], msg->rcv.src_port);

/* TODO FIX INPUT PARAMS*/
	group = find_group_in_subnet_table(*ps->subnet_table,
			ip,
			msg->rcv.src_port);
		group = 0;

		LM_DBG("Found <%d>\n", group);
	}

	pvt.flags = PV_VAL_INT|PV_TYPE_INT;
	pvt.rs.s = NULL;
	pvt.rs.len = 0;
	pvt.ri = group;

	if (pv_set_value(msg, ppv->sp, (int)EQ_T, &pvt) < 0) {
		LM_ERR("setting of pvar failed\n");
		return -1;
	}

	return 1;
}
Exemplo n.º 14
0
/**
 * rest_post_method - performs an HTTP POST request, stores results in pvars
 * @msg:		sip message struct
 * @url:		HTTP URL to be queried
 * @ctype:		Value for the "Content-Type: " header of the request
 * @body:		Body of the request
 * @body_pv:	pseudo var which will hold the result body
 * @ctype_pv:	pvar which will hold the result content type
 * @code_pv:	pvar to hold the HTTP return code
 */
int rest_post_method(struct sip_msg *msg, char *url, char *body, char *ctype,
                     pv_spec_p body_pv, pv_spec_p ctype_pv, pv_spec_p code_pv)
{
	CURLcode rc;
	CURL *handle = NULL;
	long http_rc;
	str st = { 0, 0 };
	str res_body = { 0, 0 };
	pv_value_t pv_val;

	handle = curl_easy_init();
	if (!handle) {
		LM_ERR("Init curl handle failed!\n");
		clean_header_list;
		return -1;
	}

	if (ctype) {
		sprintf(print_buff, "Content-Type: %s", ctype);
		header_list = curl_slist_append(header_list, print_buff);
	}

	if (header_list)
		w_curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header_list);

	w_curl_easy_setopt(handle, CURLOPT_URL, url);

	w_curl_easy_setopt(handle, CURLOPT_POST, 1);
	w_curl_easy_setopt(handle, CURLOPT_POSTFIELDS, body);

	w_curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, connection_timeout);
	w_curl_easy_setopt(handle, CURLOPT_TIMEOUT, curl_timeout);

	w_curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);
	w_curl_easy_setopt(handle, CURLOPT_STDERR, stdout);
	w_curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);

	w_curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_func);
	w_curl_easy_setopt(handle, CURLOPT_WRITEDATA, &res_body);

	w_curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, header_func);
	w_curl_easy_setopt(handle, CURLOPT_HEADERDATA, &st);

	if (ssl_capath)
		w_curl_easy_setopt(handle, CURLOPT_CAPATH, ssl_capath);

	if (!ssl_verifypeer)
		w_curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);

	if (!ssl_verifyhost)
		w_curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);

	rc = curl_easy_perform(handle);
	clean_header_list;

	if (code_pv) {
		curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_rc);
		LM_DBG("Last response code: %ld\n", http_rc);

		pv_val.flags = PV_VAL_INT|PV_TYPE_INT;
		pv_val.ri = (int)http_rc;

		if (pv_set_value(msg, code_pv, 0, &pv_val) != 0) {
			LM_ERR("Set code pv value failed!\n");
			goto cleanup;
		}
	}

	if (rc != CURLE_OK) {
		LM_ERR("curl_easy_perform: %s\n", curl_easy_strerror(rc));
		goto cleanup;
	}

	trim(&res_body);

	pv_val.flags = PV_VAL_STR;
	pv_val.rs = res_body;

	if (pv_set_value(msg, body_pv, 0, &pv_val) != 0) {
		LM_ERR("Set body pv value failed!\n");
		goto cleanup;
	}

	if (res_body.s) {
		pkg_free(res_body.s);
	}

	if (ctype_pv) {
		pv_val.rs = st;

		if (pv_set_value(msg, ctype_pv, 0, &pv_val) != 0) {
			LM_ERR("Set content type pv value failed!\n");
			goto cleanup;
		}

		if (st.s)
			pkg_free(st.s);
	}

	curl_easy_cleanup(handle);
	return 1;

cleanup:
	curl_easy_cleanup(handle);
	return -1;
}
Exemplo n.º 15
0
enum async_ret_code resume_async_http_req(int fd, struct sip_msg *msg, void *_param)
{
	CURLcode rc;
	CURLMcode mrc;
	rest_async_param *param = (rest_async_param *)_param;
	int running, max_fd;
	long http_rc;
	fd_set rset, wset, eset;
	pv_value_t val;

	mrc = curl_multi_perform(multi_handle, &running);
	if (mrc != CURLM_OK) {
		LM_ERR("curl_multi_perform: %s\n", curl_multi_strerror(mrc));
		return -1;
	}
	LM_DBG("running handles: %d\n", running);

	if (running == running_handles) {
		async_status = ASYNC_CONTINUE;
		return 1;
	}

	if (running > running_handles) {
		LM_BUG("incremented handles!!");
		/* default async status is DONE */
		return -1;
	}

	running_handles = running;

	FD_ZERO(&rset);
	mrc = curl_multi_fdset(multi_handle, &rset, &wset, &eset, &max_fd);
	if (mrc != CURLM_OK) {
		LM_ERR("curl_multi_fdset: %s\n", curl_multi_strerror(mrc));
		/* default async status is DONE */
		return -1;
	}

	if (max_fd == -1) {
		if (running_handles != 0) {
			LM_BUG("running_handles == %d", running_handles);
			abort();
			/* default async status is DONE */
			return -1;
		}

		if (FD_ISSET(fd, &rset)) {
			LM_BUG("fd %d is still in rset!", fd);
			abort();
			/* default async status is DONE */
			return -1;
		}

	} else if (FD_ISSET(fd, &rset)) {
		LM_DBG("fd %d still transfering...\n", fd);
		async_status = ASYNC_CONTINUE;
		return 1;
	}

	if (del_transfer(fd) != 0) {
		LM_BUG("failed to delete fd %d", fd);
		abort();
		/* default async status is DONE */
		return -1;
	}

	mrc = curl_multi_remove_handle(multi_handle, param->handle);
	if (mrc != CURLM_OK) {
		LM_ERR("curl_multi_remove_handle: %s\n", curl_multi_strerror(mrc));
		/* default async status is DONE */
		return -1;
	}

	val.flags = PV_VAL_STR;
	val.rs = param->body;
	if (pv_set_value(msg, param->body_pv, 0, &val) != 0)
		LM_ERR("failed to set output body pv\n");

	if (param->ctype_pv) {
		val.rs = param->ctype;
		if (pv_set_value(msg, param->ctype_pv, 0, &val) != 0)
			LM_ERR("failed to set output ctype pv\n");
	}

	if (param->code_pv) {
		rc = curl_easy_getinfo(param->handle, CURLINFO_RESPONSE_CODE, &http_rc);
		if (rc != CURLE_OK) {
			LM_ERR("curl_easy_getinfo: %s\n", curl_easy_strerror(rc));
			http_rc = 0;
		}

		LM_DBG("Last response code: %ld\n", http_rc);

		val.flags = PV_VAL_INT|PV_TYPE_INT;
		val.ri = (int)http_rc;
		if (pv_set_value(msg, param->code_pv, 0, &val) != 0)
			LM_ERR("failed to set output code pv\n");
	}

	pkg_free(param->body.s);
	if (param->ctype_pv && param->ctype.s)
		pkg_free(param->ctype.s);
	curl_easy_cleanup(param->handle);
	pkg_free(param);

	/* default async status is DONE */
	return 1;
}
Exemplo n.º 16
0
/**
 * rest_put_method - performs an HTTP PUT request, stores results in pvars
 * @msg:                sip message struct
 * @url:                HTTP URL to be queried
 * @ctype:              Value for the "Content-Type: " header of the request
 * @body:               Body of the request
 * @body_pv:    pseudo var which will hold the result body
 * @ctype_pv:   pvar which will hold the result content type
 * @code_pv:    pvar to hold the HTTP return code
 */
int rest_put_method(struct sip_msg *msg, char *url, char *body, char *ctype,
                     pv_spec_p body_pv, pv_spec_p ctype_pv, pv_spec_p code_pv)
{
	CURLcode rc;
	long http_rc;
	str st = { 0, 0 };
	str res_body = { NULL, 0 }, tbody, ttype;
	pv_value_t pv_val;

	rest_trace_param_t tparam;

	/*Init handle for first use*/
	if (!sync_handle) {
		sync_handle = curl_easy_init();
		if (!sync_handle) {
			LM_ERR("Init curl handle failed!\n");
			goto cleanup;
		}
	} else {
		curl_easy_reset(sync_handle);
	}

	if (ctype) {
		sprintf(print_buff, "Content-Type: %s", ctype);
		header_list = curl_slist_append(header_list, print_buff);
	}

	if (tls_dom) {
		w_curl_easy_setopt(sync_handle, CURLOPT_SSLCERT, tls_dom->cert.s);
		w_curl_easy_setopt(sync_handle, CURLOPT_SSLKEY, tls_dom->pkey.s);
		tls_api.release_domain(tls_dom);
		tls_dom = NULL;
	}

	if (header_list)
		w_curl_easy_setopt(sync_handle, CURLOPT_HTTPHEADER, header_list);

	w_curl_easy_setopt(sync_handle, CURLOPT_URL, url);
	if (curl_http_version != CURL_HTTP_VERSION_NONE)
		w_curl_easy_setopt(sync_handle, CURLOPT_HTTP_VERSION, curl_http_version);

	w_curl_easy_setopt(sync_handle, CURLOPT_CUSTOMREQUEST, "PUT");
	w_curl_easy_setopt(sync_handle, CURLOPT_POSTFIELDS, body);

	w_curl_easy_setopt(sync_handle, CURLOPT_CONNECTTIMEOUT, connection_timeout);
	w_curl_easy_setopt(sync_handle, CURLOPT_TIMEOUT, curl_timeout);

	w_curl_easy_setopt(sync_handle, CURLOPT_VERBOSE, 1);
	w_curl_easy_setopt(sync_handle, CURLOPT_STDERR, stdout);
	w_curl_easy_setopt(sync_handle, CURLOPT_FAILONERROR, 0);

	w_curl_easy_setopt(sync_handle, CURLOPT_WRITEFUNCTION, write_func);
	w_curl_easy_setopt(sync_handle, CURLOPT_WRITEDATA, &res_body);

	w_curl_easy_setopt(sync_handle, CURLOPT_HEADERFUNCTION, header_func);
	w_curl_easy_setopt(sync_handle, CURLOPT_HEADERDATA, &st);

	if (ssl_capath)
		w_curl_easy_setopt(sync_handle, CURLOPT_CAPATH, ssl_capath);

	if (!ssl_verifypeer)
		w_curl_easy_setopt(sync_handle, CURLOPT_SSL_VERIFYPEER, 0L);

	if (!ssl_verifyhost)
		w_curl_easy_setopt(sync_handle, CURLOPT_SSL_VERIFYHOST, 0L);

	/* trace rest request */
	if ( rest_trace_enabled() ) {
		memset( &tparam, 0, sizeof tparam);

		tparam.callid = msg->callid->body;

		w_curl_easy_setopt(sync_handle, CURLOPT_DEBUGFUNCTION, trace_rest_request_cb);
		w_curl_easy_setopt(sync_handle, CURLOPT_DEBUGDATA, &tparam);
	}

	rc = curl_easy_perform(sync_handle);
	clean_header_list;
	if (code_pv) {
		curl_easy_getinfo(sync_handle, CURLINFO_RESPONSE_CODE, &http_rc);
		LM_DBG("Last response code: %ld\n", http_rc);

		pv_val.flags = PV_VAL_INT|PV_TYPE_INT;
		pv_val.ri = (int)http_rc;

		if (pv_set_value(msg, code_pv, 0, &pv_val) != 0) {
			LM_ERR("Set code pv value failed!\n");
			return -1;
		}
	}

	if (rc != CURLE_OK) {
		LM_ERR("curl_easy_perform: %s\n", curl_easy_strerror(rc));
		return -1;
	}

	tbody = res_body;
	trim(&tbody);

	pv_val.flags = PV_VAL_STR;
	pv_val.rs = tbody;

	if (pv_set_value(msg, body_pv, 0, &pv_val) != 0) {
		LM_ERR("Set body pv value failed!\n");
		return -1;
	}

	if (res_body.s) {
		pkg_free(res_body.s);
	}

	if (ctype_pv) {
		ttype = st;
		trim(&ttype);

		pv_val.rs = ttype;

		if (pv_set_value(msg, ctype_pv, 0, &pv_val) != 0) {
			LM_ERR("Set content type pv value failed!\n");
			return -1;
		}
	}

	if (st.s)
		pkg_free(st.s);

	return 1;

cleanup:
	clean_header_list;
	if (tls_dom) {
		tls_api.release_domain(tls_dom);
		tls_dom = NULL;
	}
	return -1;
}
Exemplo n.º 17
0
enum async_ret_code resume_async_http_req(int fd, struct sip_msg *msg, void *_param)
{
	CURLcode rc;
	CURLMcode mrc;
	rest_async_param *param = (rest_async_param *)_param;
	int running = 0, max_fd;
	long http_rc;
	fd_set rset, wset, eset;
	pv_value_t val;
	int ret = 1, retr;
	CURLM *multi_handle;

	multi_handle = param->multi_list->multi_handle;

	retr = 0;
	do {
		mrc = curl_multi_perform(multi_handle, &running);
		if (mrc != CURLM_CALL_MULTI_PERFORM)
			break;
		LM_DBG("retry last perform...\n");
		usleep(_async_resume_retr_itv);
		retr += _async_resume_retr_itv;
	} while (retr < _async_resume_retr_timeout);

	if (mrc != CURLM_OK) {
		LM_ERR("curl_multi_perform: %s\n", curl_multi_strerror(mrc));
		return -1;
	}

	LM_DBG("running handles: %d\n", running);
	if (running == 1) {
		LM_DBG("transfer in progress...\n");
		async_status = ASYNC_CONTINUE;
		return 1;
	}

	if (running != 0) {
		LM_BUG("non-zero running handles!! (%d)", running);
		abort();
	}

	FD_ZERO(&rset);
	mrc = curl_multi_fdset(multi_handle, &rset, &wset, &eset, &max_fd);
	if (mrc != CURLM_OK) {
		LM_ERR("curl_multi_fdset: %s\n", curl_multi_strerror(mrc));
		ret = -1;
		goto out;
	}

	if (max_fd == -1) {
		if (FD_ISSET(fd, &rset)) {
			LM_BUG("fd %d is still in rset!", fd);
			abort();
		}

	} else if (FD_ISSET(fd, &rset)) {
		LM_DBG("fd %d still transferring...\n", fd);
		async_status = ASYNC_CONTINUE;
		return 1;
	}

	curl_slist_free_all(param->header_list);

	if (del_transfer(fd) != 0) {
		LM_BUG("failed to delete fd %d", fd);
		abort();
	}

	mrc = curl_multi_remove_handle(multi_handle, param->handle);
	if (mrc != CURLM_OK) {
		LM_ERR("curl_multi_remove_handle: %s\n", curl_multi_strerror(mrc));
		/* default async status is ASYNC_DONE */
		return -1;
	}
	put_multi(param->multi_list);

	val.flags = PV_VAL_STR;
	val.rs = param->body;
	if (pv_set_value(msg, param->body_pv, 0, &val) != 0)
		LM_ERR("failed to set output body pv\n");

	if (param->ctype_pv) {
		val.rs = param->ctype;
		if (pv_set_value(msg, param->ctype_pv, 0, &val) != 0)
			LM_ERR("failed to set output ctype pv\n");
	}

	if (param->code_pv) {
		rc = curl_easy_getinfo(param->handle, CURLINFO_RESPONSE_CODE, &http_rc);
		if (rc != CURLE_OK) {
			LM_ERR("curl_easy_getinfo: %s\n", curl_easy_strerror(rc));
			http_rc = 0;
		}

		LM_DBG("Last response code: %ld\n", http_rc);

		val.flags = PV_VAL_INT|PV_TYPE_INT;
		val.ri = (int)http_rc;
		if (pv_set_value(msg, param->code_pv, 0, &val) != 0)
			LM_ERR("failed to set output code pv\n");
	}

out:
	pkg_free(param->body.s);
	if (param->ctype_pv && param->ctype.s)
		pkg_free(param->ctype.s);
	curl_easy_cleanup(param->handle);
	if ( param->tparam ) {
		pkg_free( param->tparam );
	}
	pkg_free(param);

	/* default async status is ASYNC_DONE */
	return ret;
}
Exemplo n.º 18
0
static int dp_translate_f(struct sip_msg *msg, char *str1, char *str2,
                          char *attr_spec)
{

	int dpid;
	str input, output;
	dpl_id_p idp;
	dp_param_p id_par, repl_par;
	str attrs, *attrs_par;
	dp_connection_list_p connection;
	pv_value_t pval;
	str partition_name;

	if (!msg)
		return -1;

	/* verify first param's value */
	id_par = (dp_param_p) str1;

	if (dp_get_ivalue(msg, id_par, &dpid) != 0){
		LM_ERR("no dpid value\n");
		return -1;
	}

	switch( id_par->type ) {
		case DP_VAL_INT :
			if (dp_get_svalue(msg, id_par->v.pv_id.partition,
							    &partition_name)) {
				LM_ERR("invalid partition\n");
				return -1;
			}
			goto GET_CONN;
		case DP_VAL_SPEC :
			if (dp_get_svalue(msg, id_par->v.sp[1],
							    &partition_name)) {
				LM_ERR("invalid partition\n");
				return -1;
			}
		GET_CONN:
			if (!(id_par->hash = dp_get_connection(&partition_name))) {
				LM_ERR("invalid partition\n");
				return -1;
			}

			break;
		default :
			break;
	}

	LM_DBG("dpid is %i partition is %.*s\n", dpid,
			id_par->hash->partition.len, id_par->hash->partition.s);

	repl_par = (str2!=NULL) ? ((dp_param_p)str2) : default_par2;
	if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){
		LM_ERR("invalid param 2\n");
		return -1;
	}

	LM_DBG("input is %.*s\n", input.len, input.s);
	connection = id_par->hash;

	/* ref the data for reading */
	lock_start_read( connection->ref_lock );

	if ((idp = select_dpid(connection, dpid, connection->crt_index)) == 0) {
		LM_DBG("no information available for dpid %i\n", dpid);
		goto error;
	}

	LM_DBG("Checking with dpid %i\n", idp->dp_id);

	attrs_par =  attr_spec ? &attrs : NULL;
	if (translate(msg, input, &output, idp, attrs_par) != 0) {
		LM_DBG("could not translate %.*s "
			"with dpid %i\n", input.len, input.s, idp->dp_id);
		goto error;
	}

	LM_DBG("input %.*s with dpid %i => output %.*s\n",
			input.len, input.s, idp->dp_id, output.len, output.s);

	/* set the output */
	if (dp_update(msg, &repl_par->v.sp[0], &repl_par->v.sp[1], &output) != 0) {
		LM_ERR("cannot set the output\n");
		goto error;
	}

	/* we are done reading -> unref the data */
	lock_stop_read( connection->ref_lock );

	if (attr_spec) {
		pval.flags = PV_VAL_STR;
		pval.rs = attrs;

		if (pv_set_value(msg, (pv_spec_p)attr_spec, 0, &pval) != 0) {
			LM_ERR("failed to set value '%.*s' for the attr pvar!\n",
			        attrs.len, attrs.s);
			goto error;
		}
	}

	return 1;

error:
	/* we are done reading -> unref the data */
	lock_stop_read( connection->ref_lock );

	return -1;
}
Exemplo n.º 19
0
/* Checks, if the request (sip_msg *_m) comes from a host in a set
 * (set-id or -1 for all sets)
 */
int ds_is_in_list(struct sip_msg *_m, pv_spec_t *pv_ip, pv_spec_t *pv_port,
													int set, int active_only)
{
	pv_value_t val;
	ds_set_p list;
	struct ip_addr *ip;
	int_str avp_val;
	int port;
	int j,k;

	/* get the address to test */
	if (pv_get_spec_value( _m, pv_ip, &val)!=0) {
		LM_ERR("failed to get IP value from PV\n");
		return -1;
	}
	if ( (val.flags&PV_VAL_STR)==0 ) {
		LM_ERR("IP PV val is not string\n");
		return -1;
	}
	if ( (ip=str2ip( &val.rs ))==NULL ) {
		LM_ERR("IP val is not IP <%.*s>\n",val.rs.len,val.rs.s);
		return -1;
	}

	/* get the port to test */
	if (pv_port) {
		if (pv_get_spec_value( _m, pv_port, &val)!=0) {
			LM_ERR("failed to get PORT value from PV\n");
			return -1;
		}
		if ( (val.flags&PV_VAL_INT)==0 ) {
			LM_ERR("PORT PV val is not integer\n");
			return -1;
		}
		port = val.ri;
	} else {
		port = 0;
	}

	memset(&val, 0, sizeof(pv_value_t));
	val.flags = PV_VAL_INT|PV_TYPE_INT;

	for(list = _ds_list; list!= NULL; list= list->next) {
		if ((set == -1) || (set == list->id)) {
			/* interate through all elements/destinations in the list */
			for(j=0; j<list->nr; j++) {
				/* interate through all IPs of each destination */
				for(k=0 ; k<list->dlist[j].ips_cnt ; k++ ) {
					if ( (list->dlist[j].ports[k]==0 || port==0
					|| port==list->dlist[j].ports[k]) &&
					ip_addr_cmp( ip, &list->dlist[j].ips[k]) ) {
						/* matching destination */
						if (active_only &&
						(list->dlist[j].flags&(DS_INACTIVE_DST|DS_PROBING_DST)) )
							continue;
						if(set==-1 && ds_setid_pvname.s!=0) {
							val.ri = list->id;
							if(pv_set_value(_m, &ds_setid_pv,
									(int)EQ_T, &val)<0)
							{
								LM_ERR("setting PV failed\n");
								return -2;
							}
						}
						if (attrs_avp_name>= 0) {
							avp_val.s = list->dlist[j].attrs;
						if(add_avp(AVP_VAL_STR|attrs_avp_type,attrs_avp_name,avp_val)!=0)
								return -1;
						}
						return 1;
					}
				}
			}
		}
	}
	return -1;
}
Exemplo n.º 20
0
/* ret= 0! if action -> end of list(e.g DROP), 
      > 0 to continue processing next actions
   and <0 on error */
int do_action(struct action* a, struct sip_msg* msg)
{
	int ret;
	int v;
	int sec,usec;
	union sockaddr_union* to;
	struct proxy_l* p;
	char* tmp;
	char *new_uri, *end, *crt;
	int len,i;
	int user = 0;
	int expires = 0;
	str vals[5];
	str result;
	struct sip_uri uri, next_hop;
	struct sip_uri *u;
	unsigned short port;
	int cmatch;
	struct action *aitem;
	struct action *adefault;
	pv_spec_t *spec;
	pv_elem_p model;
	pv_value_t val;
	pv_elem_t *pve;
	str name_s;
	struct timeval start;
	int end_time;
	action_elem_t *route_params_bak;
	int route_params_number_bak;

	/* reset the value of error to E_UNSPEC so avoid unknowledgable
	   functions to return with error (status<0) and not setting it
	   leaving there previous error; cache the previous value though
	   for functions which want to process it */
	prev_ser_error=ser_error;
	ser_error=E_UNSPEC;

	start_expire_timer(start,execmsgthreshold);

	ret=E_BUG;
	switch ((unsigned char)a->type){
		case DROP_T:
				script_trace("core", "drop", msg, a->line) ;
				action_flags |= ACT_FL_DROP;
		case EXIT_T:
				script_trace("core", "exit", msg, a->line) ;
				ret=0;
				action_flags |= ACT_FL_EXIT;
			break;
		case RETURN_T:
				script_trace("core", "return", msg, a->line) ;
				if (a->elem[0].type == SCRIPTVAR_ST)
				{
					spec = (pv_spec_t*)a->elem[0].u.data;
					if(pv_get_spec_value(msg, spec, &val)!=0
						|| (val.flags&PV_VAL_NULL))
					{
						ret=-1;
					} else {
						if(!(val.flags&PV_VAL_INT))
							ret = 1;
						else
							ret = val.ri;
					}
					pv_value_destroy(&val);
				} else {
					ret=a->elem[0].u.number;
				}
				action_flags |= ACT_FL_RETURN;
			break;
		case FORWARD_T:
			script_trace("core", "forward", msg, a->line) ;
			if (a->elem[0].type==NOSUBTYPE){
				/* parse uri and build a proxy */
				if (msg->dst_uri.len) {
					ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
						&next_hop);
					u = &next_hop;
				} else {
					ret = parse_sip_msg_uri(msg);
					u = &msg->parsed_uri;
				}
				if (ret<0) {
					LM_ERR("forward: bad_uri dropping packet\n");
					break;
				}
				/* create a temporary proxy*/
				p=mk_proxy(u->maddr_val.len?&u->maddr_val:&u->host,
					u->port_no, u->proto, (u->type==SIPS_URI_T)?1:0 );
				if (p==0){
					LM_ERR("bad host name in uri, dropping packet\n");
					ret=E_BAD_ADDRESS;
					goto error_fwd_uri;
				}
				ret=forward_request(msg, p);
				free_proxy(p); /* frees only p content, not p itself */
				pkg_free(p);
				if (ret==0) ret=1;
			}else if ((a->elem[0].type==PROXY_ST)) {
				ret=forward_request(msg,(struct proxy_l*)a->elem[0].u.data);
				if (ret==0) ret=1;
			}else{
				LM_ALERT("BUG in forward() types %d, %d\n",
						a->elem[0].type, a->elem[1].type);
				ret=E_BUG;
			}
			break;
		case SEND_T:
			script_trace("core", "send", msg, a->line) ;
			if (a->elem[0].type!= PROXY_ST){
				LM_ALERT("BUG in send() type %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if (a->elem[1].u.data) {
				if (a->elem[1].type != SCRIPTVAR_ELEM_ST){
					LM_ALERT("BUG in send() header type %d\n",a->elem[1].type);
					ret=E_BUG;
					break;
				} else {
					pve = (pv_elem_t *)a->elem[1].u.data;
				}
			} else {
				pve = NULL;
			}
			to=(union sockaddr_union*)
					pkg_malloc(sizeof(union sockaddr_union));
			if (to==0){
				LM_ERR("memory allocation failure\n");
				ret=E_OUT_OF_MEM;
				break;
			}
			
			p=(struct proxy_l*)a->elem[0].u.data;
			
			ret=hostent2su(to, &p->host, p->addr_idx,
						(p->port)?p->port:SIP_PORT );
			if (ret==0){
				if (pve) {
					if ( pv_printf_s(msg, pve, &name_s)!=0 || 
							name_s.len == 0 || name_s.s == NULL) {
						LM_WARN("cannot get string for value\n");
						ret=E_UNSPEC;
						break;
					}
					/* build new msg */
					tmp = pkg_malloc(msg->len + name_s.len);
					if (!tmp) {
						LM_ERR("memory allocation failure\n");
						ret = E_OUT_OF_MEM;
						break;
					}
					LM_DBG("searching for first line %d\n",
							msg->first_line.len);
					/* search first line of previous msg */
					/* copy headers */
					len = msg->first_line.len;
					memcpy(tmp, msg->buf, len);
					memcpy(tmp + len, name_s.s, name_s.len);
					memcpy(tmp + len + name_s.len,
							msg->buf + len, msg->len - len);
					ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/,
							tmp, msg->len + name_s.len);
					pkg_free(tmp);
				} else {
					ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/,
							msg->buf, msg->len);
				}
				if (ret!=0 && p->host.h_addr_list[p->addr_idx+1])
					p->addr_idx++;
			}
			pkg_free(to);
			if (ret==0)
				ret=1;
			break;
		case LOG_T:
			script_trace("core", "log", msg, a->line) ;
			if ((a->elem[0].type!=NUMBER_ST)|(a->elem[1].type!=STRING_ST)){
				LM_ALERT("BUG in log() types %d, %d\n",
						a->elem[0].type, a->elem[1].type);
				ret=E_BUG;
				break;
			}
			LM_GEN1(a->elem[0].u.number, "%s", a->elem[1].u.string);
			ret=1;
			break;
		case APPEND_BRANCH_T:
			script_trace("core", "append_branch", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in append_branch %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[0].u.s.s==NULL) {
				ret = append_branch(msg, 0, &msg->dst_uri, &msg->path_vec,
					get_ruri_q(), getb0flags(), msg->force_send_socket);
				/* reset all branch info */
				msg->force_send_socket = 0;
				setb0flags(0);
				set_ruri_q(Q_UNSPECIFIED);
				if(msg->dst_uri.s!=0)
					pkg_free(msg->dst_uri.s);
				msg->dst_uri.s = 0;
				msg->dst_uri.len = 0;
				if(msg->path_vec.s!=0)
					pkg_free(msg->path_vec.s);
				msg->path_vec.s = 0;
				msg->path_vec.len = 0;
			} else {
				ret = append_branch(msg, &a->elem[0].u.s, &msg->dst_uri, 
					&msg->path_vec, a->elem[1].u.number, getb0flags(),
					msg->force_send_socket);
			}
			break;
		case REMOVE_BRANCH_T:
			script_trace("core", "remove_branch", msg, a->line) ;
			if (a->elem[0].type == SCRIPTVAR_ST) {
				spec = (pv_spec_t*)a->elem[0].u.data;
				if( pv_get_spec_value(msg, spec, &val)!=0
				|| (val.flags&PV_VAL_NULL) || !(val.flags&PV_VAL_INT) ) {
					ret=-1;
					break;
				}
				i = val.ri;
			} else {
				i=a->elem[0].u.number;
			}
			ret = (remove_branch((unsigned int)i)==0)?1:-1;
			break;
		case LEN_GT_T:
			script_trace("core", "len_gt", msg, a->line) ;
			if (a->elem[0].type!=NUMBER_ST) {
				LM_ALERT("BUG in len_gt type %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			ret = (msg->len >= (unsigned int)a->elem[0].u.number) ? 1 : -1;
			break;
		case SET_DEBUG_T:
			script_trace("core", "set_debug", msg, a->line) ;
			if (a->elem[0].type==NUMBER_ST)
				set_proc_debug_level(a->elem[0].u.number);
			else
				reset_proc_debug_level();
			ret = 1;
			break;
		case SETFLAG_T:
			script_trace("core", "setflag", msg, a->line) ;
			ret = setflag( msg, a->elem[0].u.number );
			break;
		case RESETFLAG_T:
			script_trace("core", "resetflag", msg, a->line) ;
			ret = resetflag( msg, a->elem[0].u.number );
			break;
		case ISFLAGSET_T:
			script_trace("core", "isflagset", msg, a->line) ;
			ret = isflagset( msg, a->elem[0].u.number );
			break;
		case SETSFLAG_T:
			script_trace("core", "setsflag", msg, a->line) ;
			ret = setsflag( a->elem[0].u.number );
			break;
		case RESETSFLAG_T:
			script_trace("core", "resetsflag", msg, a->line) ;
			ret = resetsflag( a->elem[0].u.number );
			break;
		case ISSFLAGSET_T:
			script_trace("core", "issflagset", msg, a->line) ;
			ret = issflagset( a->elem[0].u.number );
			break;
		case SETBFLAG_T:
			script_trace("core", "setbflag", msg, a->line) ;
			ret = setbflag( a->elem[0].u.number, a->elem[1].u.number );
			break;
		case RESETBFLAG_T:
			script_trace("core", "resetbflag", msg, a->line) ;
			ret = resetbflag( a->elem[0].u.number, a->elem[1].u.number  );
			break;
		case ISBFLAGSET_T:
			script_trace("core", "isbflagset", msg, a->line) ;
			ret = isbflagset( a->elem[0].u.number, a->elem[1].u.number  );
			break;
		case ERROR_T:
			script_trace("core", "error", msg, a->line) ;
			if ((a->elem[0].type!=STRING_ST)|(a->elem[1].type!=STRING_ST)){
				LM_ALERT("BUG in error() types %d, %d\n",
						a->elem[0].type, a->elem[1].type);
				ret=E_BUG;
				break;
			}
			LM_ERR("error(\"%s\", \"%s\") not implemented yet\n",
				a->elem[0].u.string, a->elem[1].u.string);
			ret=1;
			break;
		case ROUTE_T:
			script_trace("route", rlist[a->elem[0].u.number].name, msg, a->line) ;
			if (a->elem[0].type!=NUMBER_ST){
				LM_ALERT("BUG in route() type %d\n",
						a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if ((a->elem[0].u.number>RT_NO)||(a->elem[0].u.number<0)){
				LM_ALERT("BUG - invalid routing table number in"
							"route(%lu)\n", a->elem[0].u.number);
				ret=E_CFG;
				break;
			}
			/* check if the route has parameters */
			if (a->elem[1].type != 0) {
				if (a->elem[1].type != NUMBER_ST || a->elem[2].type != SCRIPTVAR_ELEM_ST) {
					LM_ALERT("BUG in route() type %d/%d\n",
							a->elem[1].type, a->elem[2].type);
					ret=E_BUG;
					break;
				}
				route_params_bak = route_params;
				route_params = (action_elem_t *)a->elem[2].u.data;
				route_params_number_bak = route_params_number;
				route_params_number = a->elem[1].u.number;

				return_code=run_actions(rlist[a->elem[0].u.number].a, msg);
				route_params = route_params_bak;
				route_params_number = route_params_number_bak;
			} else {
				return_code=run_actions(rlist[a->elem[0].u.number].a, msg);
			}
			ret=return_code;
			break;
		case REVERT_URI_T:
			script_trace("core", "revert_uri", msg, a->line) ;
			if (msg->new_uri.s) {
				pkg_free(msg->new_uri.s);
				msg->new_uri.len=0;
				msg->new_uri.s=0;
				msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
			};
			ret=1;
			break;
		case SET_HOST_T:
		case SET_HOSTPORT_T:
		case SET_USER_T:
		case SET_USERPASS_T:
		case SET_PORT_T:
		case SET_URI_T:
		case PREFIX_T:
		case STRIP_T:
		case STRIP_TAIL_T:
				script_trace("core", 
					(unsigned char)a->type == SET_HOST_T     ? "set_host" :
					(unsigned char)a->type == SET_HOSTPORT_T ? "set_hostport" : 
					(unsigned char)a->type == SET_USER_T     ? "set_user" :
					(unsigned char)a->type == SET_USERPASS_T ? "set_userpass" : 
					(unsigned char)a->type == SET_PORT_T     ? "set_port" :
					(unsigned char)a->type == SET_URI_T      ? "set_uri" : 
					(unsigned char)a->type == PREFIX_T       ? "prefix" :
					(unsigned char)a->type == STRIP_T  ? "strip" : "strip_tail",
					msg, a->line);
				user=0;
				if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
					if (a->elem[0].type!=NUMBER_ST) {
						LM_ALERT("BUG in set*() type %d\n",
							a->elem[0].type);
						break;
					}
				} else if (a->elem[0].type!=STR_ST){
					LM_ALERT("BUG in set*() type %d\n",
							a->elem[0].type);
					ret=E_BUG;
					break;
				}
				if (a->type==SET_URI_T) {
					if (set_ruri( msg, &a->elem[0].u.s) ) {
						LM_ERR("failed to set new RURI\n");
						ret=E_OUT_OF_MEM;
						break;
					}
					ret=1;
					break;
				}
				if (msg->new_uri.s) {
					tmp=msg->new_uri.s;
					len=msg->new_uri.len;
				}else{
					tmp=msg->first_line.u.request.uri.s;
					len=msg->first_line.u.request.uri.len;
				}
				if (parse_uri(tmp, len, &uri)<0){
					LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp);
					ret=E_UNSPEC;
					break;
				}
				
				new_uri=pkg_malloc(MAX_URI_SIZE);
				if (new_uri==0){
					LM_ERR("memory allocation failure\n");
					ret=E_OUT_OF_MEM;
					break;
				}
				end=new_uri+MAX_URI_SIZE;
				crt=new_uri;
				/* begin copying */
				len = (uri.user.len?uri.user.s:uri.host.s) - tmp;
				if (crt+len>end) goto error_uri;
				memcpy(crt,tmp,len);crt+=len;

				if (a->type==PREFIX_T) {
					if (crt+a->elem[0].u.s.len>end) goto error_uri;
					memcpy( crt, a->elem[0].u.s.s, a->elem[0].u.s.len);
					crt+=a->elem[0].u.s.len;
					/* whatever we had before, with prefix we have username 
					   now */
					user=1;
				}

				if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
					tmp=a->elem[0].u.s.s;
					len=a->elem[0].u.s.len;
				} else if (a->type==STRIP_T) {
					if (a->elem[0].u.number>uri.user.len) {
						LM_WARN("too long strip asked; "
								" deleting username: %lu of <%.*s>\n",
								a->elem[0].u.number, uri.user.len, uri.user.s);
						len=0;
					} else if (a->elem[0].u.number==uri.user.len) {
						len=0;
					} else {
						tmp=uri.user.s + a->elem[0].u.number;
						len=uri.user.len - a->elem[0].u.number;
					}
				} else if (a->type==STRIP_TAIL_T) {
					if (a->elem[0].u.number>uri.user.len) {
						LM_WARN("too long strip_tail asked;"
								" deleting username: %lu of <%.*s>\n",
								a->elem[0].u.number, uri.user.len, uri.user.s);
						len=0;
					} else if (a->elem[0].u.number==uri.user.len) {
						len=0;
					} else {
						tmp=uri.user.s;
						len=uri.user.len - a->elem[0].u.number;
					}
				} else {
					tmp=uri.user.s;
					len=uri.user.len;
				}

				if (len){
					if(crt+len>end) goto error_uri;
					memcpy(crt,tmp,len);crt+=len;
					user=1; /* we have an user field so mark it */
				}

				if (a->type==SET_USERPASS_T) tmp=0;
				else tmp=uri.passwd.s;
				/* passwd */
				if (tmp){
					len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
					*crt=':'; crt++;
					memcpy(crt,tmp,len);crt+=len;
				}
				/* host */
				if (user || tmp){ /* add @ */
					if(crt+1>end) goto error_uri;
					*crt='@'; crt++;
				}
				if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
					tmp=a->elem[0].u.s.s;
					len=a->elem[0].u.s.len;
				} else {
					tmp=uri.host.s;
					len = uri.host.len;
				}
				if (tmp){
					if(crt+len>end) goto error_uri;
					memcpy(crt,tmp,len);crt+=len;
				}
				/* port */
				if (a->type==SET_HOSTPORT_T) tmp=0;
				else if (a->type==SET_PORT_T) {
					tmp=a->elem[0].u.s.s;
					len=a->elem[0].u.s.len;
				} else {
					tmp=uri.port.s;
					len = uri.port.len;
				}
				if (tmp && len>0){
					if(crt+len+1>end) goto error_uri;
					*crt=':'; crt++;
					memcpy(crt,tmp,len);crt+=len;
				}
				/* params */
				tmp=uri.params.s;
				if (tmp){
					/* include in param string the starting ';' */
					len=uri.params.len+1;
					tmp--;
					if(crt+len+1>end) goto error_uri;
					/* if a maddr param is present, strip it out */
					if (uri.maddr.len &&
					(a->type==SET_HOSTPORT_T || a->type==SET_HOST_T)) {
						memcpy(crt,tmp,uri.maddr.s-tmp-1);
						crt+=uri.maddr.s-tmp-1;
						memcpy(crt,uri.maddr_val.s+uri.maddr_val.len,
							tmp+len-uri.maddr_val.s-uri.maddr_val.len);
						crt+=tmp+len-uri.maddr_val.s-uri.maddr_val.len;
					} else {
						memcpy(crt,tmp,len);crt+=len;
					}
				}
				/* headers */
				tmp=uri.headers.s;
				if (tmp){
					len=uri.headers.len; if(crt+len+1>end) goto error_uri;
					*crt='?'; crt++;
					memcpy(crt,tmp,len);crt+=len;
				}
				*crt=0; /* null terminate the thing */
				/* copy it to the msg */
				if (msg->new_uri.s) pkg_free(msg->new_uri.s);
				msg->new_uri.s=new_uri;
				msg->new_uri.len=crt-new_uri;
				msg->parsed_uri_ok=0;
				ret=1;
				break;
		case SET_DSTURI_T:
			script_trace("core", "set_dsturi", msg, a->line) ;
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in setdsturi() type %d\n",
							a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if(set_dst_uri(msg, &a->elem[0].u.s)!=0)
				ret = -1;
			else
				ret = 1;
			break;
		case SET_DSTHOST_T:
		case SET_DSTPORT_T:
			script_trace("core", (unsigned char) a->type == SET_DSTHOST_T ?
						 "set_dsturi" : "set_dstport", msg, a->line);
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in domain setting type %d\n",
							a->elem[0].type);
				ret=E_BUG;
				break;
			}

			tmp = msg->dst_uri.s;
			len = msg->dst_uri.len;

			if (tmp == NULL || len == 0) {
				LM_ERR("failure - null uri\n");
				ret = E_UNSPEC;
				break;
			}
			if (a->type == SET_DSTHOST_T &&
					(a->elem[0].u.s.s == NULL || a->elem[0].u.s.len == 0)) {
				LM_ERR("cannot set a null uri domain\n");
				break;
			}
			if (parse_uri(tmp, len, &uri)<0) {
				LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp);
				break;
			}
			new_uri=pkg_malloc(MAX_URI_SIZE);
			if (new_uri == NULL) {
				LM_ERR("memory allocation failure\n");
				ret=E_OUT_OF_MEM;
				break;
			}
			end=new_uri+MAX_URI_SIZE;
			crt=new_uri;
			len = (uri.user.len?uri.user.s:uri.host.s) - tmp;
			if (crt+len>end) goto error_uri;
			memcpy(crt,tmp,len);
			crt += len;
			/* user */
			tmp = uri.user.s;
			len = uri.user.len;
			if (tmp) {
				if (crt+len>end) goto error_uri;
				memcpy(crt,tmp,len);
				crt += len;
				user = 1;
			}
			/* passwd */
			tmp = uri.passwd.s;
			len = uri.passwd.len;
			if (user || tmp) {
				if (crt+len+1>end) goto error_uri;
				*crt++=':';
				memcpy(crt, tmp, len);
				crt += len;
			}
			/* host */
			if (a->type==SET_DSTHOST_T) {
				tmp = a->elem[0].u.s.s;
				len = a->elem[0].u.s.len;
			} else {
				tmp = uri.host.s;
				len = uri.host.len;
			}
			if (tmp) {
				if (user) {
					if (crt+1>end) goto error_uri;
					*crt++='@';
				}
				if (crt+len+1>end) goto error_uri;
				memcpy(crt, tmp, len);
				crt += len;
			}
			/* port */
			if (a->type==SET_DSTPORT_T) {
				tmp = a->elem[0].u.s.s;
				len = a->elem[0].u.s.len;
			} else {
				tmp = uri.port.s;
				len = uri.port.len;
			}
			if (tmp) {
				if (crt+len+1>end) goto error_uri;
				*crt++=':';
				memcpy(crt, tmp, len);
				crt += len;
			}
			/* params */
			tmp=uri.params.s;
			if (tmp){
				len=uri.params.len; if(crt+len+1>end) goto error_uri;
				*crt++=';';
				memcpy(crt,tmp,len);
				crt += len;
			}
			/* headers */
			tmp=uri.headers.s;
			if (tmp){
				len=uri.headers.len; if(crt+len+1>end) goto error_uri;
				*crt++='?';
				memcpy(crt,tmp,len);
				crt += len;
			}
			*crt=0; /* null terminate the thing */
			/* copy it to the msg */
			pkg_free(msg->dst_uri.s);
			msg->dst_uri.s=new_uri;
			msg->dst_uri.len=crt-new_uri;
			ret = 1;
			break;
		case RESET_DSTURI_T:
			script_trace("core", "reset_dsturi", msg, a->line) ;
			if(msg->dst_uri.s!=0)
				pkg_free(msg->dst_uri.s);
			msg->dst_uri.s = 0;
			msg->dst_uri.len = 0;
			ret = 1;
			break;
		case ISDSTURISET_T:
			script_trace("core", "isdsturiset", msg, a->line) ;
			if(msg->dst_uri.s==0 || msg->dst_uri.len<=0)
				ret = -1;
			else
				ret = 1;
			break;
		case IF_T:
			script_trace("core", "if", msg, a->line) ;
				/* if null expr => ignore if? */
				if ((a->elem[0].type==EXPR_ST)&&a->elem[0].u.data){
					v=eval_expr((struct expr*)a->elem[0].u.data, msg, 0);
					/* set return code to expr value */
					if (v<0 || (action_flags&ACT_FL_RETURN)
							|| (action_flags&ACT_FL_EXIT) ){
						if (v==EXPR_DROP || (action_flags&ACT_FL_RETURN)
								|| (action_flags&ACT_FL_EXIT) ){ /* hack to quit on DROP*/
							ret=0;
							return_code = 0;
							break;
						}else{
							LM_WARN("error in expression (l=%d)\n", a->line);
						}
					}
					
					ret=1;  /*default is continue */
					if (v>0) {
						if ((a->elem[1].type==ACTIONS_ST)&&a->elem[1].u.data){
							ret=run_action_list(
									(struct action*)a->elem[1].u.data,msg );
							return_code = ret;
						} else return_code = v;
					}else{
						if ((a->elem[2].type==ACTIONS_ST)&&a->elem[2].u.data){
							ret=run_action_list(
								(struct action*)a->elem[2].u.data,msg);
							return_code = ret;
						} else return_code = v;
					}
				}
			break;
		case WHILE_T:
			script_trace("core", "while", msg, a->line) ;
				/* if null expr => ignore if? */
				if ((a->elem[0].type==EXPR_ST)&&a->elem[0].u.data){
					len = 0;
					while(1)
					{
						if(len++ >= max_while_loops)
						{
							LM_INFO("max while loops are encountered\n");
							break;
						}
						v=eval_expr((struct expr*)a->elem[0].u.data, msg, 0);
						/* set return code to expr value */
						if (v<0 || (action_flags&ACT_FL_RETURN)
								|| (action_flags&ACT_FL_EXIT) ){
							if (v==EXPR_DROP || (action_flags&ACT_FL_RETURN)
									|| (action_flags&ACT_FL_EXIT) ){
								ret=0;
								return_code = 0;
								break;
							}else{
								LM_WARN("error in expression (l=%d)\n",
										a->line);
							}
						}
					
						ret=1;  /*default is continue */
						if (v>0) {
							if ((a->elem[1].type==ACTIONS_ST)
									&&a->elem[1].u.data){
								ret=run_action_list(
									(struct action*)a->elem[1].u.data,msg );
								/* check if return was done */
								if ((action_flags&ACT_FL_RETURN)
								|| (action_flags&ACT_FL_EXIT) ){
									break;
								}
								return_code = ret;
							} else {
								/* we should not get here */
								return_code = v;
								break;
							}
						} else {
							/* condition was false */
							return_code = v;
							break;
						}
					}
				}
			break;
		case CACHE_STORE_T:
			script_trace("core", "cache_store", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_store() - first argument not of"
						" type string [%d]\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_store()  - second argument not of "
						"type string [%d]\n", a->elem[1].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[2].type!=STR_ST)) {
				LM_ALERT("BUG in cache_store() - third argument not of type"
						" string%d\n", a->elem[2].type );
				ret=E_BUG;
				break;
			}

			str val_s;

			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			/* parse the value argument */
			pve = (pv_elem_t *)a->elem[2].u.data;
			if ( pv_printf_s(msg, pve, &val_s)!=0 || 
			val_s.len == 0 || val_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			/* get the expires value */
			if ( a->elem[3].type == SCRIPTVAR_ST )
			{
				spec = (pv_spec_t*)a->elem[3].u.data;
				memset(&val, 0, sizeof(pv_value_t));
				if(pv_get_spec_value(msg, spec, &val) < 0)
				{
					LM_DBG("Failed to get scriptvar value while executing cache_store\n");
					ret=E_BUG;
					break;
				}
				if (!(val.flags&PV_VAL_INT))
				{
					LM_ERR("Wrong value for cache_store expires, not an integer [%.*s]\n",
							val.rs.len, val.rs.s);
				}
				expires = val.ri;
			}
			else
			if ( a->elem[3].type == NUMBER_ST )
			{
				expires = (int)a->elem[3].u.number;
			}

			ret = cachedb_store( &a->elem[0].u.s, &name_s, &val_s,expires);

			break;
		case CACHE_REMOVE_T:
			script_trace("core", "cache_remove", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_remove() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_remove() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}
			ret = cachedb_remove( &a->elem[0].u.s, &name_s);
			break;
		case CACHE_FETCH_T:
			script_trace("core", "cache_fetch", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[2].type!=SCRIPTVAR_ST){
				LM_ALERT("BUG in cache_fetch() type %d\n",
						a->elem[2].type);
				ret=E_BUG;
				break;
			}
			str aux = {0, 0};
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			ret = cachedb_fetch( &a->elem[0].u.s, &name_s, &aux);
			if(ret > 0)
			{
				val.rs = aux;
				val.flags = PV_VAL_STR;

				spec = (pv_spec_t*)a->elem[2].u.data;
				if (pv_set_value(msg, spec, 0, &val) < 0) {
					LM_ERR("cannot set the variable value\n");
					pkg_free(aux.s);
					return -1;
				}
				pkg_free(aux.s);
			}
			
			break;
		case CACHE_COUNTER_FETCH_T:
			script_trace("core", "cache_counter_fetch", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[2].type!=SCRIPTVAR_ST){
				LM_ALERT("BUG in cache_fetch() type %d\n",
						a->elem[2].type);
				ret=E_BUG;
				break;
			}
			int aux_counter;
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			ret = cachedb_counter_fetch( &a->elem[0].u.s, &name_s, &aux_counter);
			if(ret > 0)
			{
				val.ri = aux_counter;
				val.flags = PV_TYPE_INT|PV_VAL_INT;

				spec = (pv_spec_t*)a->elem[2].u.data;
				if (pv_set_value(msg, spec, 0, &val) < 0) {
					LM_ERR("cannot set the variable value\n");
					pkg_free(aux.s);
					return -1;
				}
			}
			break;
		case CACHE_ADD_T:
			script_trace("core", "cache_add", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_add() - first argument not of"
						" type string [%d]\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_add()  - second argument not of "
						"type string [%d]\n", a->elem[1].type );
				ret=E_BUG;
				break;
			}

			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			int increment=0;

			/* get the increment value */
			if ( a->elem[2].type == SCRIPTVAR_ST )
			{
				spec = (pv_spec_t*)a->elem[2].u.data;
				memset(&val, 0, sizeof(pv_value_t));
				if(pv_get_spec_value(msg, spec, &val) < 0)
				{
					LM_DBG("Failed to get scriptvar value while executing cache_add\n");
					ret=E_BUG;
					break;
				}
				if (!(val.flags&PV_VAL_INT))
				{
					LM_ERR("Wrong value for cache_add, not an integer [%.*s]\n",
							val.rs.len, val.rs.s);
				}
				increment = val.ri;
			}
			else if ( a->elem[2].type == NUMBER_ST )
			{
				increment = (int)a->elem[2].u.number;
			}

			expires = (int)a->elem[3].u.number;

			/* TODO - return the new value to script ? */
			ret = cachedb_add(&a->elem[0].u.s, &name_s, increment,expires,NULL);
			break;
		case CACHE_SUB_T:
			script_trace("core", "cache_sub", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_sub() - first argument not of"
						" type string [%d]\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_sub()  - second argument not of "
						"type string [%d]\n", a->elem[1].type );
				ret=E_BUG;
				break;
			}

			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			int decrement=0;

			/* get the increment value */
			if ( a->elem[2].type == SCRIPTVAR_ST )
			{
				spec = (pv_spec_t*)a->elem[2].u.data;
				memset(&val, 0, sizeof(pv_value_t));
				if(pv_get_spec_value(msg, spec, &val) < 0)
				{
					LM_DBG("Failed to get scriptvar value while executing cache_sub\n");
					ret=E_BUG;
					break;
				}
				if (!(val.flags&PV_VAL_INT))
				{
					LM_ERR("Wrong value for cache_sub, not an integer [%.*s]\n",
							val.rs.len, val.rs.s);
				}
				decrement = val.ri;
			}
			else if ( a->elem[2].type == NUMBER_ST )
			{
				decrement = (int)a->elem[2].u.number;
			}

			expires = (int)a->elem[3].u.number;

			/* TODO - return new value to script ? */
			ret = cachedb_sub(&a->elem[0].u.s, &name_s, decrement,expires,NULL);
			break;
		case CACHE_RAW_QUERY_T:
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[2].u.data != NULL && 
				a->elem[2].type!=STR_ST){
				LM_ALERT("BUG in cache_raw_query() type %d\n",
						a->elem[2].type);
				ret=E_BUG;
				break;
			}
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			cdb_raw_entry **cdb_reply;
			int val_number=0,i,j;
			int key_number=0;
			pvname_list_t *cdb_res,*it;
			int_str avp_val;
			int_str avp_name;
			unsigned short avp_type;

			if (a->elem[2].u.data) {
				cdb_res = (pvname_list_t*)a->elem[2].u.data;
				for (it=cdb_res;it;it=it->next)
					val_number++;

				LM_DBG("The query expects %d results back\n",val_number);

				ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, &cdb_reply,val_number,&key_number);
				if (ret >= 0 && val_number > 0) {
					for (i=key_number-1; i>=0;i--) {
						it=cdb_res;
						for (j=0;j < val_number;j++) {
							avp_type = 0;
							if (pv_get_avp_name(msg,&it->sname.pvp,&avp_name.n,
								&avp_type) != 0) {
								LM_ERR("cannot get avp name [%d/%d]\n",i,j);
								goto next_avp;
							}
							
							switch (cdb_reply[i][j].type) {
								case CDB_INT:
									avp_val.n = cdb_reply[i][j].val.n; 
									break;
								case CDB_STR:
									avp_type |= AVP_VAL_STR;
									avp_val.s = cdb_reply[i][j].val.s;
									break;
								default:
									LM_WARN("Unknown type %d\n",cdb_reply[i][j].type);
									goto next_avp;
							}
							if (add_avp(avp_type,avp_name.n,avp_val) != 0) {
								LM_ERR("Unable to add AVP\n");
								free_raw_fetch(cdb_reply,val_number,key_number);
								return -1;
							}
next_avp:
							if (it) {
								it = it->next;
								if (it==NULL);
									break;
							}
						}
					}
					free_raw_fetch(cdb_reply,val_number,key_number);
				}
			}
			else
				ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, NULL,0,NULL);
			break;
		case XDBG_T:
			script_trace("core", "xdbg", msg, a->line) ;
			if (a->elem[0].type == SCRIPTVAR_ELEM_ST)
			{
				if (xdbg(msg, a->elem[0].u.data, val.rs.s) < 0)
				{
					LM_ALERT("Cannot print message");
					break;
				}
			}
			else
			{
				LM_ALERT("BUG in xdbg() type %d\n", a->elem[0].type);
				ret=E_BUG;
			}
			break;
		case XLOG_T:
			script_trace("core", "xlog", msg, a->line) ;
			if (a->elem[1].u.data != NULL)
			{
				if (a->elem[1].type != SCRIPTVAR_ELEM_ST)
				{
					LM_ALERT("BUG in xlog() type %d\n", a->elem[1].type);
					ret=E_BUG;
					break;
				}
				if (a->elem[0].type != STR_ST)
				{
					LM_ALERT("BUG in xlog() type %d\n", a->elem[0].type);
					ret=E_BUG;
					break;
				}
				if (xlog_2(msg,a->elem[0].u.data, a->elem[1].u.data) < 0)
				{
					LM_ALERT("Cannot print xlog debug message");
					break;
				}
			}
			else
			{
				if (a->elem[0].type != SCRIPTVAR_ELEM_ST)
				{
					LM_ALERT("BUG in xlog() type %d\n", a->elem[0].type);
					ret=E_BUG;
					break;
				}
				if (xlog_1(msg,a->elem[0].u.data, val.rs.s) < 0)
				{
					LM_ALERT("Cannot print xlog debug message");
					break;
				}
			}

			break;
		case RAISE_EVENT_T:
			script_trace("core", "raise_event", msg, a->line) ;
			if (a->elem[0].type != NUMBER_ST) {
				LM_ERR("invalid event id\n");
				ret=E_BUG;
				break;
			}
			if (a->elem[2].u.data) {
				/* three parameters specified */
				ret = evi_raise_script_event(msg, (event_id_t)a->elem[0].u.number,
						a->elem[1].u.data, a->elem[2].u.data);
			} else {
				/* two parameters specified */
				ret = evi_raise_script_event(msg, (event_id_t)a->elem[0].u.number,
						NULL, a->elem[1].u.data);
			}
			if (ret <= 0) {
				LM_ERR("cannot raise event\n");
				ret=E_UNSPEC;
				break;
			}
			break;
		case SUBSCRIBE_EVENT_T:
			script_trace("core", "subscribe_event", msg, a->line) ;
			if (a->elem[0].type != STR_ST || a->elem[1].type != STR_ST) {
				LM_ERR("BUG in subscribe arguments\n");
				ret=E_BUG;
				break;
			}
			if (a->elem[2].u.data) {
				if (a->elem[2].type != NUMBER_ST) {
					LM_ERR("BUG in subscribe expiration time\n");
					ret=E_BUG;
					break;
				} else {
					i = a->elem[2].u.number;
				}
			} else {
				i = 0;
			}

			name_s.s = a->elem[0].u.data;
			name_s.len = strlen(name_s.s);
			/* result should be the socket */
			result.s = a->elem[1].u.data;
			result.len = strlen(result.s);
			ret = evi_event_subscribe(name_s, result, i, 0);
			break;

		case CONSTRUCT_URI_T:
			script_trace("core", "construct_uri", msg, a->line) ;
			for (i=0;i<5;i++)
			{
				pve = (pv_elem_t *)a->elem[i].u.data;
				if (pve->spec.getf)
				{
					if ( pv_printf_s(msg, pve, &vals[i])!=0 || 
						vals[i].len == 0 || vals[i].s == NULL) 
					{
						LM_WARN("cannot get string for value\n");
						ret=E_BUG;
						return -1;
					}
				}
				else
					vals[i] = pve->text;
			}
			
			result.s = construct_uri(&vals[0],&vals[1],&vals[2],&vals[3],&vals[4],
					&result.len);

			if (result.s)
			{
				int_str res;
				int avp_name;
				unsigned short avp_type;

				spec = (pv_spec_t*)a->elem[5].u.data;
				if (pv_get_avp_name( msg, &(spec->pvp), &avp_name,
						&avp_type)!=0){
					LM_CRIT("BUG in getting AVP name\n");
					return -1;
				}

				res.s = result;
				if (add_avp(AVP_VAL_STR|avp_type, avp_name, res)<0){
					LM_ERR("cannot add AVP\n");
					return -1;
				}
			}

			break;
		case GET_TIMESTAMP_T:
			script_trace("core", "get_timestamp", msg, a->line) ;
			if (get_timestamp(&sec,&usec) == 0) {
				int avp_name;
				int_str res;
				unsigned short avp_type;

				spec = (pv_spec_t*)a->elem[0].u.data;
				if (pv_get_avp_name(msg, &(spec->pvp), &avp_name,
						&avp_type) != 0) {
					LM_CRIT("BUG in getting AVP name\n");
					return -1;
				}

				res.n = sec;
				if (add_avp(avp_type, avp_name, res) < 0) {
					LM_ERR("cannot add AVP\n");
					return -1;
				}

				spec = (pv_spec_t*)a->elem[1].u.data;
				if (pv_get_avp_name(msg, &(spec->pvp), &avp_name,
						&avp_type) != 0) {
					LM_CRIT("BUG in getting AVP name\n");
					return -1;
				}

				res.n = usec;
				if (add_avp(avp_type, avp_name, res) < 0) {
					LM_ERR("cannot add AVP\n");
					return -1;
				}
			} else {
				LM_ERR("failed to get time\n");
				return -1;
			}
			break;
		case SWITCH_T:
			script_trace("core", "switch", msg, a->line) ;
			if (a->elem[0].type!=SCRIPTVAR_ST){
				LM_ALERT("BUG in switch() type %d\n",
						a->elem[0].type);
				ret=E_BUG;
				break;
			}
			spec = (pv_spec_t*)a->elem[0].u.data;
			if(pv_get_spec_value(msg, spec, &val)!=0)
			{
				LM_ALERT("BUG - no value in switch()\n");
				ret=E_BUG;
				break;
			}

			/* get the value of pvar */
			if(a->elem[1].type!=ACTIONS_ST) {
				LM_ALERT("BUG in switch() actions\n");
				ret=E_BUG;
				break;
			}
			return_code=1;
			adefault = NULL;
			aitem = (struct action*)a->elem[1].u.data;
			cmatch=0;
			while(aitem)
			{
				if((unsigned char)aitem->type==DEFAULT_T)
					adefault=aitem;
				if(cmatch==0)
				{
					if(aitem->elem[0].type==STR_ST)
					{
						if(val.flags&PV_VAL_STR
								&& val.rs.len==aitem->elem[0].u.s.len
								&& strncasecmp(val.rs.s, aitem->elem[0].u.s.s,
									val.rs.len)==0)
							cmatch = 1;
					} else { /* number */
						if(val.flags&PV_VAL_INT && 
								val.ri==aitem->elem[0].u.number)
							cmatch = 1;
					}
				}
				if(cmatch==1)
				{
					if(aitem->elem[1].u.data)
					{
						return_code=run_action_list(
							(struct action*)aitem->elem[1].u.data, msg);
						if ((action_flags&ACT_FL_RETURN) ||
						(action_flags&ACT_FL_EXIT))
							break;
					}
					if(aitem->elem[2].u.number==1)
						break;
				}
				aitem = aitem->next;
			}
			if((cmatch==0) && (adefault!=NULL))
			{
				LM_DBG("switch: running default statement\n");
				if(adefault->elem[0].u.data)
					return_code=run_action_list(
						(struct action*)adefault->elem[0].u.data, msg);
			}
			ret=return_code;
			break;
		case MODULE_T:
			script_trace("module", ((cmd_export_t*)(a->elem[0].u.data))->name,
				msg, a->line) ;
			if ( (a->elem[0].type==CMD_ST) && a->elem[0].u.data ) {
				ret=((cmd_export_t*)(a->elem[0].u.data))->function(msg,
						 (char*)a->elem[1].u.data, (char*)a->elem[2].u.data,
						 (char*)a->elem[3].u.data, (char*)a->elem[4].u.data,
						 (char*)a->elem[5].u.data, (char*)a->elem[6].u.data);
			}else{
				LM_ALERT("BUG in module call\n");
			}
			break;
		case FORCE_RPORT_T:
			script_trace("core", "force_rport", msg, a->line) ;
			msg->msg_flags|=FL_FORCE_RPORT;
			ret=1; /* continue processing */
			break;
		case FORCE_LOCAL_RPORT_T:
			script_trace("core", "force_local_rport", msg, a->line) ;
			msg->msg_flags|=FL_FORCE_LOCAL_RPORT;
			ret=1; /* continue processing */
			break;
		case SET_ADV_ADDR_T:
			script_trace("core", "set_adv_addr", msg, a->line) ;
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in set_advertised_address() "
						"type %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			str adv_addr;
			pve = (pv_elem_t *)a->elem[0].u.data;
			if ( pv_printf_s(msg, pve, &adv_addr)!=0 || 
			adv_addr.len == 0 || adv_addr.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}
			LM_DBG("adv address = [%.*s]\n",adv_addr.len,adv_addr.s);
			msg->set_global_address=adv_addr;
			ret=1; /* continue processing */
			break;
		case SET_ADV_PORT_T:
			script_trace("core", "set_adv_port", msg, a->line) ;
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in set_advertised_port() "
						"type %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}

			msg->set_global_port=*((str*)a->elem[0].u.data);
			ret=1; /* continue processing */
			break;
#ifdef USE_TCP
		case FORCE_TCP_ALIAS_T:
			script_trace("core", "force_tcp_alias", msg, a->line) ;
			if ( msg->rcv.proto==PROTO_TCP
#ifdef USE_TLS
					|| msg->rcv.proto==PROTO_TLS
#endif
			   ){
				
				if (a->elem[0].type==NOSUBTYPE)	port=msg->via1->port;
				else if (a->elem[0].type==NUMBER_ST)
					port=(int)a->elem[0].u.number;
				else{
					LM_ALERT("BUG in force_tcp_alias"
							" port type %d\n", a->elem[0].type);
					ret=E_BUG;
					break;
				}
						
				if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
									msg->rcv.proto)!=0){
					LM_ERR("tcp alias failed\n");
					ret=E_UNSPEC;
					break;
				}
			}
#endif
			ret=1; /* continue processing */
			break;
		case FORCE_SEND_SOCKET_T:
			script_trace("core", "force_send_socket", msg, a->line) ;
			if (a->elem[0].type!=SOCKETINFO_ST){
				LM_ALERT("BUG in force_send_socket argument"
						" type: %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			msg->force_send_socket=(struct socket_info*)a->elem[0].u.data;
			ret=1; /* continue processing */
			break;
		case SERIALIZE_BRANCHES_T:
			script_trace("core", "serialize_branches", msg, a->line) ;
			if (a->elem[0].type!=NUMBER_ST){
				LM_ALERT("BUG in serialize_branches argument"
						" type: %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if (serialize_branches(msg,(int)a->elem[0].u.number)!=0) {
				LM_ERR("serialize_branches failed\n");
				ret=E_UNSPEC;
				break;
			}
			ret=1; /* continue processing */
			break;
		case NEXT_BRANCHES_T:
			script_trace("core", "next_branches", msg, a->line) ;
			if ((ret=next_branches(msg))<0) {
				LM_ERR("next_branches failed\n");
				ret=E_UNSPEC;
				break;
			}
			/* continue processing */
			break;
		case EQ_T:
		case COLONEQ_T:
		case PLUSEQ_T:
		case MINUSEQ_T:
		case DIVEQ_T:
		case MULTEQ_T:
		case MODULOEQ_T:
		case BANDEQ_T:
		case BOREQ_T:
		case BXOREQ_T:
			ret = do_assign(msg, a);
			break;
		case USE_BLACKLIST_T:
			script_trace("core", "use_blacklist", msg, a->line) ;
			mark_for_search((struct bl_head*)a->elem[0].u.data, 1);
			break;
		case UNUSE_BLACKLIST_T:
			script_trace("core", "unuse_blacklist", msg, a->line);
			mark_for_search((struct bl_head*)a->elem[0].u.data, 0);
			break;
		case PV_PRINTF_T:
			script_trace("core", "pv_printf", msg, a->line);
			ret = -1;
			spec = (pv_spec_p)a->elem[0].u.data;
			if(!pv_is_w(spec))
			{
				LM_ERR("read only PV in first parameter of pv_printf\n");
				goto error;
			}

			model = (pv_elem_p)a->elem[1].u.data;

			memset(&val, 0, sizeof(pv_value_t));
			if(pv_printf_s(msg, model, &val.rs)!=0)
			{
				LM_ERR("cannot eval second parameter\n");
				goto error;
			}
			val.flags = PV_VAL_STR;
			if(pv_set_value(msg, spec, EQ_T, &val)<0)
			{
				LM_ERR("setting PV failed\n");
				goto error;
			}
			
			ret = 1;
			break;
		case SCRIPT_TRACE_T:
			script_trace("core", "script_trace", msg, a->line);
			if (a->elem[0].type==NOSUBTYPE) {
				use_script_trace = 0;
			} else {
				
				use_script_trace = 1;
				
				if (a->elem[0].type != NUMBER_ST ||
					a->elem[1].type != SCRIPTVAR_ELEM_ST) {

					LM_ERR("BUG in use_script_trace() arguments\n");
					ret=E_BUG;
					break;
				}

				if (a->elem[2].type!=NOSUBTYPE) {
					script_trace_info = (char *)a->elem[2].u.data;
				} else {
					script_trace_info = NULL;
				}

				script_trace_log_level = (int)a->elem[0].u.number;
				script_trace_elem = *(pv_elem_p)a->elem[1].u.data;
			}

			break;
		default:
			LM_ALERT("BUG - unknown type %d\n", a->type);
			goto error;
	}

	if((unsigned char)a->type!=IF_T && (unsigned char)a->type!=ROUTE_T)
		return_code = ret;
/*skip:*/

	update_longest_action();
	return ret;

error:
	LM_ERR("error at line: %d\n", a->line);
	update_longest_action();
	return ret;
	
error_uri:
	LM_ERR("set*: uri too long\n");
	if (new_uri) pkg_free(new_uri);
	update_longest_action();
	return E_UNSPEC;
error_fwd_uri:
	update_longest_action();
	return ret;
}
Exemplo n.º 21
0
/*
 * Check if domain is local
 */
int is_domain_local(struct sip_msg *msg, str* _host, char *pvar)
{
	pv_spec_t *pv = (pv_spec_t *)pvar;
	pv_value_t val;
	db_val_t *values;

	if (db_mode == 0) {
		db_key_t keys[1];
		db_val_t vals[1];
		db_key_t cols[2];
		db_res_t* res = NULL;

		keys[0] = &domain_col;
		cols[0] = &domain_col;
		cols[1] = &domain_attrs_col;

		if (domain_dbf.use_table(db_handle, &domain_table) < 0) {
			LM_ERR("Error while trying to use domain table\n");
			return -3;
		}

		VAL_TYPE(vals) = DB_STR;
		VAL_NULL(vals) = 0;

		VAL_STR(vals).s = _host->s;
		VAL_STR(vals).len = _host->len;

		if (domain_dbf.query(db_handle, keys, 0, vals, cols, 1, 2, 0, &res) < 0
				) {
			LM_ERR("Error while querying database\n");
			return -3;
		}

		if (RES_ROW_N(res) == 0) {
			LM_DBG("Realm '%.*s' is not local\n",
			       _host->len, ZSW(_host->s));
			domain_dbf.free_result(db_handle, res);
			return -1;
		} else {
			LM_DBG("Realm '%.*s' is local\n",
			       _host->len, ZSW(_host->s));
			if (pvar) {
				/* XXX: what shall we do if there are duplicate entries? */
				/* we only check the first row - razvanc */
				values = ROW_VALUES(RES_ROWS(res));
				if (!VAL_NULL(values +1)) {
					if (VAL_TYPE(values + 1) == DB_STR) {
						val.rs = VAL_STR(values + 1);
					} else {
						val.rs.s = (char *)VAL_STRING(values + 1);
						val.rs.len = strlen(val.rs.s);
					}
					val.flags = PV_VAL_STR;
					if (pv_set_value(msg, pv, 0, &val) != 0)
						LM_ERR("Cannot set attributes value\n");
				}
			}
			domain_dbf.free_result(db_handle, res);
			return 1;
		}
	} else {
		return hash_table_lookup (msg, _host, pv);
	}

}
Exemplo n.º 22
0
int ds_count(struct sip_msg *msg, int set_id, const char *cmp, pv_spec_p ret)
{
	pv_value_t pv_val;
	ds_set_p set;
	ds_dest_p dst;
	int count, active = 0, inactive = 0, probing = 0;

	set = ds_lists[*crt_idx];

	LM_DBG("Searching for set: %d, filtering: %d\n", set_id, *cmp);

	while (set && set->id != set_id)
	{
		set = set->next;
	}

	if (!set)
	{
		LM_ERR("INVALID SET!\n");
		return -1;
	}

	for (dst = set->dlist; dst; dst = dst->next)
	{
		if (!(dst->flags & (DS_INACTIVE_DST|DS_PROBING_DST)))
		{
			active++;

		} else if (dst->flags & DS_INACTIVE_DST)
		{
			inactive++;

		} else if (dst->flags & DS_PROBING_DST)
		{
			probing++;
		}
	}

	switch (*cmp)
	{
		case DS_COUNT_ACTIVE:
			count = active;
			break;

		case DS_COUNT_ACTIVE|DS_COUNT_INACTIVE:
		case DS_COUNT_ACTIVE|DS_COUNT_PROBING:
			count = (*cmp & DS_COUNT_INACTIVE ? active + inactive :
												active + probing);
			break;

		case DS_COUNT_INACTIVE:
		case DS_COUNT_PROBING:
			count = (*cmp == DS_COUNT_INACTIVE ? inactive : probing);
			break;

		case DS_COUNT_INACTIVE|DS_COUNT_PROBING:
			count = inactive + probing;
			break;

		default:
			count = active + inactive + probing;
	}

	pv_val.flags = PV_TYPE_INT;
	pv_val.ri = count;

	if (pv_set_value(msg, ret, 0, &pv_val) != 0)
	{
		LM_ERR("SET OUTPUT value failed!\n");
		return -1;
	}

	return 1;
}
Exemplo n.º 23
0
int async_rest_method(enum rest_client_method method, struct sip_msg *msg,
                      char *url, str *body, str *ctype, async_ctx *ctx,
                      pv_spec_p body_pv, pv_spec_p ctype_pv, pv_spec_p code_pv)
{
	rest_async_param *param;
	pv_value_t val;
	long http_rc;
	int read_fd, rc;

	param = pkg_malloc(sizeof *param);
	if (!param) {
		LM_ERR("no more shm\n");
		return RCL_INTERNAL_ERR;
	}
	memset(param, '\0', sizeof *param);

	rc = start_async_http_req(msg, method, url, body, ctype,
			param, &param->body, ctype_pv ? &param->ctype : NULL, &read_fd);

	/* error occurred; no transfer done */
	if (read_fd == ASYNC_NO_IO) {
		ctx->resume_param = NULL;
		ctx->resume_f = NULL;
		/* keep default async status of NO_IO */
		pkg_free(param);
		return rc;

	/* no need for async - transfer already completed! */
	} else if (read_fd == ASYNC_SYNC) {
		if (code_pv) {
			curl_easy_getinfo(param->handle, CURLINFO_RESPONSE_CODE, &http_rc);
			LM_DBG("HTTP response code: %ld\n", http_rc);

			val.flags = PV_VAL_INT|PV_TYPE_INT;
			val.ri = (int)http_rc;
			if (pv_set_value(msg, (pv_spec_p)code_pv, 0, &val) != 0) {
				LM_ERR("failed to set output code pv\n");
				return RCL_INTERNAL_ERR;
			}
		}

		val.flags = PV_VAL_STR;
		val.rs = param->body;
		if (pv_set_value(msg, (pv_spec_p)body_pv, 0, &val) != 0) {
			LM_ERR("failed to set output body pv\n");
			return RCL_INTERNAL_ERR;
		}

		if (ctype_pv) {
			val.rs = param->ctype;
			if (pv_set_value(msg, (pv_spec_p)ctype_pv, 0, &val) != 0) {
				LM_ERR("failed to set output ctype pv\n");
				return RCL_INTERNAL_ERR;
			}
		}

		pkg_free(param->body.s);
		if (ctype_pv && param->ctype.s)
			pkg_free(param->ctype.s);
		curl_easy_cleanup(param->handle);
		pkg_free(param);

		async_status = ASYNC_SYNC;
		return rc;
	}

	ctx->resume_f = resume_async_http_req;

	param->method = method;
	param->body_pv = (pv_spec_p)body_pv;
	param->ctype_pv = (pv_spec_p)ctype_pv;
	param->code_pv = (pv_spec_p)code_pv;
	ctx->resume_param = param;

	/* async started with success */
	async_status = read_fd;
	return 1;
}
Exemplo n.º 24
0
int get_user_group(struct sip_msg *req, char *user, char *avp)
{
	static char uri_buf[MAX_URI_SIZE];
	str user_str;
	str  username;
	str  domain;
	pv_spec_t *pvs;
	pv_value_t val;
	struct re_grp *rg;
	regmatch_t pmatch;
	char *c;
	int n;

	if(user ==  NULL || fixup_get_svalue(req, (gparam_p)user, &user_str) != 0){
		LM_ERR("Invalid parameter URI\n");
		return -1;
	}

	if (get_username_domain( req, &user_str, &username, &domain)!=0){
		LM_ERR("failed to get username@domain\n");
		goto error;
	}

	if (username.s==NULL || username.len==0 ) {
		LM_DBG("no username part\n");
		return -1;
	}

	if ( 4 + username.len + 1 + domain.len + 1 > MAX_URI_SIZE ) {
		LM_ERR("URI to large!!\n");
		goto error;
	}

	*(int*)uri_buf = htonl(('s'<<24) + ('i'<<16) + ('p'<<8) + ':');
	c = uri_buf + 4;
	memcpy( c, username.s, username.len);
	c += username.len;
	*(c++) = '@';
	memcpy( c, domain.s, domain.len);
	c += domain.len;
	*c = 0;

	LM_DBG("getting groups for <%s>\n",uri_buf);
	pvs = (pv_spec_t*)avp;
	memset(&val, 0, sizeof(pv_value_t));
	val.flags = PV_VAL_INT|PV_TYPE_INT;

	/* check against all re groups */
	for( rg=re_list,n=0 ; rg ; rg=rg->next ) {
		if (regexec( &rg->re, uri_buf, 1, &pmatch, 0)==0) {
			LM_DBG("user matched to group %d!\n", rg->gid.n);

			/* match -> add the gid as AVP */
			val.ri = rg->gid.n;
			if(pv_set_value(req, pvs, (int)EQ_T, &val)<0)
			{
				LM_ERR("setting PV AVP failed\n");
				goto error;
			}
			n++;
			/* continue? */
			if (multiple_gid==0)
				break;
		}
	}

	return n?n:-1;
error:
	return -1;
}
Exemplo n.º 25
0
/* execute assignment operation */
int do_assign(struct sip_msg* msg, struct action* a)
{
	int ret;
	pv_value_t val;
	pv_spec_p dspec;

	ret = -1;
	dspec = (pv_spec_p)a->elem[0].u.data;
	if(!pv_is_w(dspec))
	{
		LM_ERR("read only PV in left expression\n");
		goto error;
	}

	memset(&val, 0, sizeof(pv_value_t));
	if(a->elem[1].type != NULLV_ST)
	{
		ret = eval_expr((struct expr*)a->elem[1].u.data, msg, &val);
		if(!((val.flags&PV_VAL_STR)||(val.flags&PV_VAL_INT))) {
			LM_ERR("no value in right expression\n");
			goto error;
		}
	}

	switch ((unsigned char)a->type){
		case EQ_T:
		case COLONEQ_T:
		case PLUSEQ_T:
		case MINUSEQ_T:
		case DIVEQ_T:
		case MULTEQ_T:
		case MODULOEQ_T:
		case BANDEQ_T:
		case BOREQ_T:
		case BXOREQ_T:
			script_trace("assign",
				(unsigned char)a->type == EQ_T      ? "equal" :
				(unsigned char)a->type == COLONEQ_T ? "colon-eq" :
				(unsigned char)a->type == PLUSEQ_T  ? "plus-eq" :
				(unsigned char)a->type == MINUSEQ_T ? "minus-eq" :
				(unsigned char)a->type == DIVEQ_T   ? "div-eq" :
				(unsigned char)a->type == MULTEQ_T  ? "mult-eq" :
				(unsigned char)a->type == MODULOEQ_T? "modulo-eq" :
				(unsigned char)a->type == BANDEQ_T  ? "b-and-eq" :
				(unsigned char)a->type == BOREQ_T   ? "b-or-eq":"b-xor-eq",
				msg, a->line);

			if(a->elem[1].type == NULLV_ST)
			{
				if(pv_set_value(msg, dspec, (int)a->type, 0)<0)
				{
					LM_ERR("setting PV failed\n");
					goto error;
				}
			} else {
				if(pv_set_value(msg, dspec, (int)a->type, &val)<0)
				{
					LM_ERR("setting PV failed\n");
					goto error;
				}
			}
			ret = 1;
		break;
		default:
			LM_ALERT("BUG -> unknown op type %d\n", a->type);
			goto error;
	}

	pv_value_destroy(&val);
	return ret;

error:
	LM_ERR("error at line: %d\n", a->line);
	pv_value_destroy(&val);
	return -1;
}
Exemplo n.º 26
0
int resume_async_exec(int fd, struct sip_msg *msg, void *param)
{
	#define MAX_LINE_SIZE 1024
	char buf[MAX_LINE_SIZE+1];
	exec_async_param *p = (exec_async_param*)param;
	pv_value_t outval;
	char *s1, *s2;
	int n, len;

	if (p->buf) {
		memcpy( buf, p->buf, p->buf_len);
		len = p->buf_len;
		shm_free(p->buf);
		p->buf = NULL;
	} else {
		len = 0;
	}

	do {
		n=read( fd, buf+len, MAX_LINE_SIZE-len);
		LM_DBG(" read %d [%.*s] \n",n, n<0?0:n,buf+len);
		if (n<0) {
			if (errno==EINTR) continue;
			if (errno==EAGAIN || errno==EWOULDBLOCK) {
				/* nothing more to read */
				if (len) {
					/* store what is left */
					if ((p->buf=(char*)shm_malloc(len))==NULL) {
						LM_ERR("failed to allocate buffer\n");
						goto error;
					}
					memcpy( p->buf, buf, len);
					p->buf_len = len;
					LM_DBG(" storing %d [%.*s] \n", p->buf_len, p->buf_len, p->buf);
				}
				/* async should continue */
				async_status = ASYNC_CONTINUE;
				return 1;
			}
			LM_ERR("read failed with %d (%s)\n",errno, strerror(errno));
			/* terminate everything */
			goto error;
		}
		/* EOF ? */
		if (n==0) {
			if (len) {
				/* take whatever is left in buffer and push it as var */
				outval.flags = PV_VAL_STR;
				outval.rs.s = buf;
				outval.rs.len = len;
				LM_DBG("setting var [%.*s]\n",outval.rs.len,outval.rs.s);
				if (pv_set_value(msg, &p->outvar->v.pve->spec, 0, &outval) < 0) {
					LM_ERR("failed to set variable :(, continuing \n");
				}
			}
			break;
		}
		/* successful reading  ( n>0 ) */
		LM_DBG(" having %d [%.*s] \n", len+n, len+n, buf);
		if (n+len==MAX_LINE_SIZE) {
			/* we have full buffer, pack it as a line */
			buf[n+len] = '\n';
			n++;
		}
		/* search for '\n' in the newly read data */
		s1 = buf;
		while ( (buf+len+n-s1>0) && ((s2=q_memchr(s1, '\n', buf+len+n-s1))!=NULL) ) {
			/* push it as var */
			outval.flags = PV_VAL_STR;
			outval.rs.s = s1;
			outval.rs.len = s2-s1;
			LM_DBG("setting var [%.*s]\n",outval.rs.len,outval.rs.s);
			if (pv_set_value(msg, &p->outvar->v.pve->spec, 0, &outval) < 0) {
				LM_ERR("failed to set variable :(, continuing \n");
			}
			s1 = s2+1;
		}
		/* any data consumed ? */
		if ( s1!=buf+len ) {
			/* yes -> shift the whole buffer to left */
			len = buf+len+n-s1;
			if (len) memmove( buf, s1, len);
		} else {
			/* no -> increase the len of the buffer */
			len += n;
		}
	}while(1);

	/* done with the async */
	shm_free(param);

	/* make sure our fd is closed by the async engine */
	async_status = ASYNC_DONE_CLOSE_FD;
	return 1;

error:
	shm_free(param);
	/* stay with default async status ASYNC_DONE */
	return -1;
	#undef MAX_LINE_SIZE
}
Exemplo n.º 27
0
int send_auth_func(struct sip_msg* msg, str* s1, str* s2) {

	int i, res;
	int index1 = -1, index2 = -1;
	map_list *mp;
	pv_value_t pvt;
	char mess[1024];

	VALUE_PAIR *send = NULL, *recv = NULL, *vp = NULL;

	if (!rh) {
		if (init_radius_handle()) {
			LM_ERR("invalid radius handle\n");
			return -1;
		}
	}

	for (i = 0; i < set_size; i++) {
		if (sets[i]->set_name.len == s1->len &&
				!strncmp(sets[i]->set_name.s, s1->s, s1->len))
				index1 = i;
		if (sets[i]->set_name.len == s2->len &&
				!strncmp(sets[i]->set_name.s, s2->s, s2->len))
				index2 = i;
	}

	if (index1 == -1) {
		LM_ERR("the first set was not found\n");
		return -1;
	}

	if (index2 == -1) {
		LM_ERR("the second set was not found\n");
		return -1;
	}

	if (make_send_message(msg, index1, &send) < 0) {
		LM_ERR("make message failed\n");
		return -1;
	}

	res = rc_auth(rh, SIP_PORT, send, &recv, mess);
	if (res!=OK_RC && res!=BADRESP_RC) {
		LM_ERR("radius authentication message failed with %s\n",
			(res==TIMEOUT_RC)?"TIMEOUT":"ERROR");
	}else{
		LM_DBG("radius authentication message sent\n");
	}

	for ( mp=sets[index2]->parsed; mp ; mp = mp->next) {
		vp = recv;
		while ( (vp=rc_avpair_get(vp, ATTRID(mp->value), VENDOR(mp->value)))!=NULL ) {
			memset(&pvt, 0, sizeof(pv_value_t));
			if (vp->type == PW_TYPE_INTEGER) {
				pvt.flags = PV_VAL_INT|PV_TYPE_INT;
				pvt.ri = vp->lvalue;
			}
			else
			if (vp->type == PW_TYPE_STRING) {
				pvt.flags = PV_VAL_STR;
				pvt.rs.s = vp->strvalue;
				pvt.rs.len = vp->lvalue;
			}
			if (pv_set_value(msg, mp->pv, (int)EQ_T, &pvt) < 0) {
				LM_ERR("setting avp failed....skipping\n");
			}
			vp = fetch_all_values ? vp->next : NULL;
		}
	}

	vp = recv;
	if (attr)
		for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
			extract_avp(vp);

	if ( res!=OK_RC && res!=BADRESP_RC)
		goto error;


	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);

	return (res==OK_RC)?1:-2;
error:
	if (send) rc_avpair_free(send);
	if (recv) rc_avpair_free(recv);
	return -1;
}
Exemplo n.º 28
0
/* TODO
 * when timeout mechanism will be available
 * rc_auth_function shall be called to try another
 * destination if the current one has timed out
 * */
int resume_send_auth(int fd, struct sip_msg *msg, void *param)
{
	int res;
	map_list *mp;
	pv_value_t pvt;
	struct rad_ctx *rctx;

	VALUE_PAIR *recv = NULL, *vp = NULL;

	rctx = (struct rad_ctx *)param;
	if (rctx == NULL) {
		LM_ERR("no context given\n");
		return -1;
	}

	res = rc_auth_resume(&rctx->ctx, &recv);

	if (res == OK_RC || res == REJECT_RC) {
		async_status = ASYNC_DONE;
	} else if (res == READBLOCK_RC) {
		async_status  = ASYNC_CONTINUE;
		return 1;
	} else {
		LM_ERR("radius authentication message failed with %s\n",
							((res==BADRESP_RC)?"BAD REPLY":"ERROR"));
		goto error;
	}

	for ( mp=sets[rctx->index2]->parsed; mp ; mp = mp->next) {
		vp = recv;
		while ( (vp=rc_avpair_get(vp, ATTRID(mp->value), VENDOR(mp->value)))!=NULL ) {
			memset(&pvt, 0, sizeof(pv_value_t));
			if (vp->type == PW_TYPE_INTEGER) {
				pvt.flags = PV_VAL_INT|PV_TYPE_INT;
				pvt.ri = vp->lvalue;
			}
			else
			if (vp->type == PW_TYPE_STRING) {
				pvt.flags = PV_VAL_STR;
				pvt.rs.s = vp->strvalue;
				pvt.rs.len = vp->lvalue;
			}
			if (pv_set_value(msg, mp->pv, (int)EQ_T, &pvt) < 0) {
				LM_ERR("setting avp failed....skipping\n");
			}
			vp = fetch_all_values ? vp->next : NULL;
		}
	}

	vp = recv;
	if (attr)
		for(; (vp = rc_avpair_get(vp, attr->value, 0)); vp = vp->next)
			extract_avp(vp);

	if ( res!=OK_RC && res!=REJECT_RC)
		goto error;


	if (rctx->send) rc_avpair_free(rctx->send);
	if (recv) rc_avpair_free(recv);

	pkg_free(rctx);

	return (res==OK_RC)?1:-2;
error:
	pkg_free(rctx);
	if (rctx->send) rc_avpair_free(rctx->send);
	if (recv) rc_avpair_free(recv);
	return -1;

}