Esempio n. 1
0
/**
 * Create a new peer.
 * - All the memory from parameters is duplicated.
 * @param fqdn - FQDN of the peer
 * @param realm - Realm of the peer
 * @param port - port of the peer to connect to
 * @returns the new peer* if ok, NULL on error
 */
peer* new_peer(str fqdn,str realm,int port)
{
	peer *x;
	x = shm_malloc(sizeof(peer));
	if (!x){
		LOG_NO_MEM("shm",sizeof(peer));
		goto error;
	}
	memset(x,0,sizeof(peer));
	shm_str_dup(x->fqdn,fqdn);
	if (!x->fqdn.s) goto error;	
	shm_str_dup(x->realm,realm);
	if (!x->realm.s) goto error;	
	x->port = port;
	x->lock = lock_alloc();
	x->lock = lock_init(x->lock);
		
	x->state = Closed;

	x->I_sock = -1;
	x->R_sock = -1;

	x->activity = time(0)-500;	
	
	x->next = 0;
	x->prev = 0;
	
	return x;
error:
	return 0;
}
Esempio n. 2
0
/**
 * Adds a failure route rule to rt. prefix, host, reply_code, and comment
 * must not contain NULL pointers.
 *
 * @param failure_tree the current route tree node
 * @param prefix the whole scan prefix
 * @param host the hostname last tried
 * @param reply_code the reply code
 * @param flags user defined flags
 * @param mask mask for user defined flags
 * @param next_domain continue routing with this domain
 * @param comment a comment for the route rule
 *
 * @return 0 on success, -1 on failure
 *
 * @see add_failure_route_to_tree()
 */
int add_failure_route_rule(struct failure_route_tree_item * failure_tree, const str * prefix,
		const str * host, const str * reply_code, flag_t flags, flag_t mask,
		const int next_domain, const str * comment) {
	struct failure_route_rule * shm_rr;
	struct failure_route_rule * rr;
	struct failure_route_rule * prev;

	if ((shm_rr = shm_malloc(sizeof(struct failure_route_rule))) == NULL) {
		LM_ERR("out of shared memory\n");
		return -1;
	}
	memset(shm_rr, 0, sizeof(struct failure_route_rule));

	if (shm_str_dup(&shm_rr->host, host) != 0) {
		goto mem_error;
	}

	if (shm_str_dup(&shm_rr->reply_code, reply_code) != 0) {
		goto mem_error;
	}

	shm_rr->flags = flags;
	shm_rr->mask = mask;
	shm_rr->next_domain = next_domain;

	if (shm_str_dup(&shm_rr->comment, comment) != 0) {
		goto mem_error;
	}

	/* before inserting into list, check priorities! */
	rr=failure_tree->rule_list;
	prev=NULL;
	while ((rr != NULL) && (rule_prio_cmp(shm_rr, rr) > 0)) {
		prev=rr;
		rr=rr->next;
	}
	if(prev){
		shm_rr->next = prev->next;
		prev->next = shm_rr;
	} else {
		shm_rr->next = failure_tree->rule_list;
		failure_tree->rule_list = shm_rr;
	}

	return 0;

mem_error:
	LM_ERR("out of shared memory\n");
	destroy_failure_route_rule(shm_rr);
	return -1;
}
Esempio n. 3
0
int dlg_add_extra(dlg_t* _d, str* _ldname, str* _rdname)
{
	if(!_d || !_ldname || !_rdname)
	{
		LM_ERR("Invalid parameters\n");
		return -1;
	}

	/* Make a copy of local Display Name */
	if(shm_str_dup(&_d->loc_dname, _ldname) < 0) return -2;
	/* Make a copy of remote Display Name */
	if(shm_str_dup(&_d->rem_dname, _rdname) < 0) return -3;

	return 0;
}
Esempio n. 4
0
/**
 * @brief duplicate dmq node
 */
dmq_node_t *shm_dup_node(dmq_node_t *node)
{
	dmq_node_t *newnode;
	if(!node) {
		LM_ERR("node is null\n");
		return NULL;
	}
	if(!node->orig_uri.s) {
		LM_ERR("nod->orig_uri.s is null\n");
		return NULL;
	}

	newnode = shm_malloc(sizeof(dmq_node_t));
	if(newnode == NULL) {
		LM_ERR("no more shm\n");
		return NULL;
	}
	memcpy(newnode, node, sizeof(dmq_node_t));
	newnode->orig_uri.s = NULL;
	if(shm_str_dup(&newnode->orig_uri, &node->orig_uri) < 0) {
		goto error;
	}
	if(parse_uri(newnode->orig_uri.s, newnode->orig_uri.len, &newnode->uri)
			< 0) {
		LM_ERR("error in parsing node uri\n");
		goto error;
	}
	return newnode;
error:
	destroy_dmq_node(newnode, 1);
	return NULL;
}
Esempio n. 5
0
/**
 * Create a new route tree root in shared memory and set it up.
 *
 * @param domain the domain name of the route tree
 * @param id the domain id of the route tree
 *
 * @return a pointer to the newly allocated route tree or NULL on
 * error, in which case it LOGs an error message.
 */
struct route_tree * create_route_tree(const str * domain, int id) {
	struct route_tree * tmp;
	if ((tmp = shm_malloc(sizeof(struct route_tree))) == NULL) {
		LM_ERR("out of shared memory\n");
		return NULL;
	}
	memset(tmp, 0, sizeof(struct route_tree));
	if (shm_str_dup(&tmp->name, domain)!=0) {
		LM_ERR("cannot duplicate string\n");
		shm_free(tmp);
		return NULL;
	}
	tmp->id = id;
	return tmp;
}
Esempio n. 6
0
/*
 * Helper to copy input string parameter into a query parameter
 */
static int set_query_param(str* param, str input)
{
	if (param->s) {
		shm_free(param->s);
		param->s = NULL;
		param->len = 0;
	}

	if (input.s && input.len > 0) {
		if (shm_str_dup(param, &input) < 0) {
			LM_ERR("Error allocating parameter\n");
			return -1;
		}
	}

	return 1;
}
Esempio n. 7
0
/**
 * Tries to add a domain to the domain map. If the given domain doesn't
 * exist, it is added. Otherwise, nothing happens.
 *
 * @param domain the domain to be added
 *
 * @return values: on succcess the numerical index of the given domain,
 * -1 on failure
 */
int add_domain(const str * domain) {
	struct route_map * tmp, * prev = NULL;
	int id = 0;
	if (!script_routes) {
		if ((script_routes = shm_malloc(sizeof(struct route_map *))) == NULL) {
			LM_ERR("out of shared memory\n");
			return -1;
		}
		memset(script_routes, 0, sizeof(struct route_map *));
	}

	tmp = *script_routes;

	while (tmp) {
		if (str_strcmp(&tmp->name, domain) == 0) {
			return tmp->no;
		}
		id = tmp->no + 1;
		prev = tmp;
		tmp = tmp->next;
	}
	if ((tmp = shm_malloc(sizeof(struct route_map))) == NULL) {
		LM_ERR("out of shared memory\n");
		return -1;
	}
	memset(tmp, 0, sizeof(struct route_map));
	if (shm_str_dup(&tmp->name, domain) != 0) {
		LM_ERR("cannot duplicate string\n");
		shm_free(tmp);
		return -1;
	}
	tmp->no = id;
	if (!prev) {
		*script_routes = tmp;
	} else {
		prev->next = tmp;
	}
	LM_INFO("domain %.*s has id %i\n", domain->len, domain->s, id);
	return id;
}
Esempio n. 8
0
frd_stats_entry_t* get_stats(str user, str prefix, str *shm_user)
{
	rw_lock_t *item_lock;

	/* First go one level below using the user key */
	frd_users_map_item_t **hm =
		(frd_users_map_item_t **)get_item(&stats_table, user, &item_lock);

	if (*hm == NULL) {
		/* First time the user is seen, we must create a hashmap */
		*hm = shm_malloc(sizeof(frd_users_map_item_t));
		if (*hm == NULL) {
			lock_stop_write(item_lock);
			LM_ERR("no more shm memory\n");
			return NULL;
		}
		lock_stop_write(item_lock);

		(*hm)->numbers_hm.size = FRD_PREFIX_HASH_SIZE;
		if (init_hash_map(&(*hm)->numbers_hm) != 0) {
			LM_ERR("cannot init hashmap\n");
			shm_free(*hm);
			return NULL;
		}

		if (shm_str_dup(&(*hm)->user, &user) != 0) {
			free_hash_map(&(*hm)->numbers_hm, destroy_stats_entry);
			shm_free(*hm);
			return NULL;
		}
	}
	lock_stop_write(item_lock);

	if (shm_user)
		*shm_user = (*hm)->user;

	frd_stats_entry_t **stats_entry =
		(frd_stats_entry_t**)get_item(&(*hm)->numbers_hm, prefix, &item_lock);

	if (*stats_entry == NULL) {
		/* First time the prefix is seen for this user */
		*stats_entry = shm_malloc(sizeof(frd_stats_entry_t));
		if (*stats_entry == NULL) {
			lock_stop_write(item_lock);
			LM_ERR("no more shm memory\n");
			return NULL;
		}
		lock_stop_write(item_lock);

		/* Now init the auxiliary info for a stats structure */
		if (!lock_init(&(*stats_entry)->lock)) {
			LM_ERR ("cannot init lock\n");
			shm_free(*stats_entry);
			return NULL;
		}
		memset(&((*stats_entry)->stats), 0, sizeof(frd_stats_t));
	}
	lock_stop_write(item_lock);

	return *stats_entry;
}
Esempio n. 9
0
/**
 * Processes an incoming message.
 * This actually just puts the message into a message queue. One worker will pick-it-up
 * and do the actual processing.
 * \note Must be called with a lock on the peer.
 * @param p - peer received from
 * @param msg - the message received
 */ 
void Rcv_Process(peer *p, AAAMessage *msg)
{
	AAASession *session=0;
	unsigned int hash; // we need this here because after the sm_processing , we might end up
					   // with no session any more
	if (msg->sessionId) session = get_session(msg->sessionId->data);
	
	if (session){
		hash=session->hash;
		switch (session->type){
			case AUTH_CLIENT_STATEFULL:
				if (is_req(msg)){
					if (msg->commandCode==IMS_ASR)
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_ASR,msg);
					else 
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_REQ,msg);
				}else {
					if (msg->commandCode==IMS_STA)
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_STA,msg);
					else
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_ANS,msg);
				}
				break;
			 case AUTH_SERVER_STATEFULL:
			 	if (is_req(msg))
			 	{
			 		auth_server_statefull_sm_process(session,AUTH_EV_RECV_REQ,msg);
			 	}else{
			 		if (msg->commandCode==IMS_ASA)
			 			auth_server_statefull_sm_process(session,AUTH_EV_RECV_ASA,msg);
			 		else
			 			auth_server_statefull_sm_process(session,AUTH_EV_RECV_ANS,msg);
			 	}
			 	break;
			default:
				break;			 
		}
		sessions_unlock(hash);
	}else{
		if (msg->sessionId){
			if (msg->commandCode == IMS_ASR) 
				auth_client_statefull_sm_process(0,AUTH_EV_RECV_ASR,msg);
			if (msg->commandCode == IMS_AAR)
			{
				session=AAACreateAuthSession(0,0,1,0,0);
				
				shm_str_dup(session->id,msg->sessionId->data); 
				auth_server_statefull_sm_process(0,AUTH_EV_RECV_REQ,msg);				
			}
			// Any other cases to think about?	 
		} 
				 
	}

	if (!put_task(p,msg)){
		LOG(L_ERR,"ERROR:Rcv_Process(): Queue refused task\n");
		AAAFreeMessage(&msg);
	}
	LOG(L_DBG,"DBG:Rcv_Process(): task added to queue\n");
	
//	AAAPrintMessage(msg);
	
}
Esempio n. 10
0
/**
 * @brief build a dmq node
 */
dmq_node_t *build_dmq_node(str *uri, int shm)
{
	dmq_node_t *ret = NULL;
	param_hooks_t hooks;
	param_t *params;

	/* For DNS-Lookups */
	static char hn[256];
	struct hostent *he;

	LM_DBG("build_dmq_node %.*s with %s memory\n", STR_FMT(uri),
			shm ? "shm" : "private");

	if(shm) {
		ret = shm_malloc(sizeof(dmq_node_t));
		if(ret == NULL) {
			LM_ERR("no more shm\n");
			goto error;
		}
		memset(ret, 0, sizeof(dmq_node_t));
		if(shm_str_dup(&ret->orig_uri, uri) < 0) {
			goto error;
		}
	} else {
		ret = pkg_malloc(sizeof(dmq_node_t));
		if(ret == NULL) {
			LM_ERR("no more pkg\n");
			goto error;
		}
		memset(ret, 0, sizeof(dmq_node_t));
		if(pkg_str_dup(&ret->orig_uri, uri) < 0) {
			goto error;
		}
	}
	set_default_dmq_node_params(ret);
	if(parse_uri(ret->orig_uri.s, ret->orig_uri.len, &ret->uri) < 0
			|| ret->uri.host.len > 254) {
		LM_ERR("error parsing uri\n");
		goto error;
	}
	/* if any parameters found, parse them */
	if(parse_params(&ret->uri.params, CLASS_ANY, &hooks, &params) < 0) {
		LM_ERR("error parsing params\n");
		goto error;
	}
	/* if any params found */
	if(params) {
		if(set_dmq_node_params(ret, params) < 0) {
			free_params(params);
			LM_ERR("error setting parameters\n");
			goto error;
		}
		free_params(params);
	} else {
		LM_DBG("no dmqnode params found\n");
	}
	/* resolve hostname */
	strncpy(hn, ret->uri.host.s, ret->uri.host.len);
	hn[ret->uri.host.len] = '\0';
	he = resolvehost(hn);
	if(he == 0) {
		LM_ERR("could not resolve %.*s\n", ret->uri.host.len, ret->uri.host.s);
		goto error;
	}
	hostent2ip_addr(&ret->ip_address, he, 0);

	return ret;

error:
	if(ret != NULL) {
		destroy_dmq_node(ret, shm);
	}
	return NULL;
}
Esempio n. 11
0
int async_send_query(sip_msg_t *msg, str *query, cfg_action_t *act)
{
	async_query_t *aq;
	unsigned int tindex = 0;
	unsigned int tlabel = 0;
	short suspend = 0;
	int dsize;
	int len;
	tm_cell_t *t = 0;

	if(query==0) {
		LM_ERR("invalid parameters\n");
		return -1;
	}

	t = tmb.t_gett();
	if (t==NULL || t==T_UNDEFINED) {
		LM_DBG("no pre-existing transaction, switching to transaction-less behavior\n");
	} else if (!ah_params.suspend_transaction) {
		LM_DBG("transaction won't be suspended\n");
	} else {
		if(tmb.t_suspend==NULL) {
			LM_ERR("http async query is disabled - tm module not loaded\n");
			return -1;
		}

		if(tmb.t_suspend(msg, &tindex, &tlabel)<0) {
			LM_ERR("failed to suspend request processing\n");
			return -1;
		}

		suspend = 1;

		LM_DBG("transaction suspended [%u:%u]\n", tindex, tlabel);
	}
	dsize = sizeof(async_query_t);
	aq = (async_query_t*)shm_malloc(dsize);

	if(aq==NULL)
	{
		LM_ERR("no more shm\n");
		goto error;
	}
	memset(aq,0,dsize);

	if(shm_str_dup(&aq->query, query)<0) {
		goto error;
	}

	aq->param = act;
	aq->tindex = tindex;
	aq->tlabel = tlabel;
	
	aq->query_params.tls_verify_peer = ah_params.tls_verify_peer;
	aq->query_params.tls_verify_host = ah_params.tls_verify_host;
	aq->query_params.suspend_transaction = suspend;
	aq->query_params.timeout = ah_params.timeout;
	aq->query_params.headers = ah_params.headers;
	aq->query_params.method = ah_params.method;
	aq->query_params.authmethod = ah_params.authmethod;
	
	q_idx++;
	snprintf(q_id, MAX_ID_LEN+1, "%u-%u", (unsigned int)getpid(), q_idx);
	strncpy(aq->id, q_id, strlen(q_id));

	aq->query_params.tls_client_cert.s = NULL;
	aq->query_params.tls_client_cert.len = 0;
	if (ah_params.tls_client_cert.s && ah_params.tls_client_cert.len > 0) {
		if (shm_str_dup(&aq->query_params.tls_client_cert, &(ah_params.tls_client_cert)) < 0) {
			LM_ERR("Error allocating aq->query_params.tls_client_cert\n");
			goto error;
		}
	}

	aq->query_params.tls_client_key.s = NULL;
	aq->query_params.tls_client_key.len = 0;
	if (ah_params.tls_client_key.s && ah_params.tls_client_key.len > 0) {
		if (shm_str_dup(&aq->query_params.tls_client_key, &(ah_params.tls_client_key)) < 0) {
			LM_ERR("Error allocating aq->query_params.tls_client_key\n");
			goto error;
		}
	}

	aq->query_params.tls_ca_path.s = NULL;
	aq->query_params.tls_ca_path.len = 0;
	if (ah_params.tls_ca_path.s && ah_params.tls_ca_path.len > 0) {
		if (shm_str_dup(&aq->query_params.tls_ca_path, &(ah_params.tls_ca_path)) < 0) {
			LM_ERR("Error allocating aq->query_params.tls_ca_path\n");
			goto error;
		}
	}

	aq->query_params.body.s = NULL;
	aq->query_params.body.len = 0;
	if (ah_params.body.s && ah_params.body.len > 0) {
		if (shm_str_dup(&aq->query_params.body, &(ah_params.body)) < 0) {
			LM_ERR("Error allocating aq->query_params.body\n");
			goto error;
		}
	}

	aq->query_params.username = NULL;
	if (ah_params.username) {
		len = strlen(ah_params.username);
		aq->query_params.username = shm_malloc(len+1);
	
		if(aq->query_params.username == NULL) {
			LM_ERR("error in shm_malloc\n");
			goto error;
		}

		strncpy(aq->query_params.username, ah_params.username, len);
		aq->query_params.username[len] = '\0';
	}

	aq->query_params.password = NULL;
	if (ah_params.password) {
		len = strlen(ah_params.password);
		aq->query_params.password = shm_malloc(len+1);
	
		if(aq->query_params.password == NULL) {
			LM_ERR("error in shm_malloc\n");
			goto error;
		}

		strncpy(aq->query_params.password, ah_params.password, len);
		aq->query_params.password[len] = '\0';
	}

	set_query_params(&ah_params);

	if(async_push_query(aq)<0) {
		LM_ERR("failed to relay query: %.*s\n", query->len, query->s);
		goto error;
	}

	if (suspend)  {
		/* force exit in config */
		return 0;
	}
	
	/* continue route processing */
	return 1;

error:

	if (suspend) {
		tmb.t_cancel_suspend(tindex, tlabel);
	}
	free_async_query(aq);
	return -1;
}
Esempio n. 12
0
void set_query_params(struct query_params *p) {
	p->headers.len = 0;
	p->headers.t = NULL;
	p->tls_verify_host = tls_verify_host;
	p->tls_verify_peer = tls_verify_peer;
	p->suspend_transaction = 1;
	p->timeout = http_timeout;
	p->method = AH_METH_DEFAULT;
	p->authmethod = default_authmethod;

	if (p->tls_client_cert.s && p->tls_client_cert.len > 0) {
		shm_free(p->tls_client_cert.s);
		p->tls_client_cert.s = NULL;
		p->tls_client_cert.len = 0;
	}
	if (tls_client_cert.s && tls_client_cert.len > 0) {
		if (shm_str_dup(&p->tls_client_cert, &tls_client_cert) < 0) {
			LM_ERR("Error allocating tls_client_cert\n");
			return;
		}
	}

	if (p->tls_client_key.s && p->tls_client_key.len > 0) {
		shm_free(p->tls_client_key.s);
		p->tls_client_key.s = NULL;
		p->tls_client_key.len = 0;
	}
	if (tls_client_key.s && tls_client_key.len > 0) {
		if (shm_str_dup(&p->tls_client_key, &tls_client_key) < 0) {
			LM_ERR("Error allocating tls_client_key\n");
			return;
		}
	}

	if (p->tls_ca_path.s && p->tls_ca_path.len > 0) {
		shm_free(p->tls_ca_path.s);
		p->tls_ca_path.s = NULL;
		p->tls_ca_path.len = 0;
	}
	if (tls_ca_path.s && tls_ca_path.len > 0) {
		if (shm_str_dup(&p->tls_ca_path, &tls_ca_path) < 0) {
			LM_ERR("Error allocating tls_ca_path\n");
			return;
		}
	}

	if (p->body.s && p->body.len > 0) {
		shm_free(p->body.s);
		p->body.s = NULL;
		p->body.len = 0;
	}
	
	if (p->username) {
		shm_free(p->username);
		p->username = NULL;
	}
	
	if (p->password) {
		shm_free(p->password);
		p->password = NULL;
	}
}
Esempio n. 13
0
void notification_socket_cb(int fd, short event, void *arg)
{
	(void)fd; /* unused */
	(void)event; /* unused */
	const async_http_worker_t *worker = (async_http_worker_t *) arg;

	int received;
	int i, len;
	async_query_t *aq;

	http_m_params_t query_params;

	str query;

	if ((received = recvfrom(worker->notication_socket[0],
			&aq, sizeof(async_query_t*),
			0, NULL, 0)) < 0) {
		LM_ERR("failed to read from socket (%d: %s)\n", errno, strerror(errno));
		return;
	}

	if(received != sizeof(async_query_t*)) {
		LM_ERR("invalid query size %d\n", received);
		return;
	}

	query = ((str)aq->query);

	query_params.timeout = aq->query_params.timeout;
	query_params.tls_verify_peer = aq->query_params.tls_verify_peer;
	query_params.tls_verify_host = aq->query_params.tls_verify_host;
	query_params.authmethod = aq->query_params.authmethod;

	query_params.headers = NULL;
	for (i = 0 ; i < aq->query_params.headers.len ; i++) {
		query_params.headers = curl_slist_append(query_params.headers, aq->query_params.headers.t[i]);
	}
	query_params.method  = aq->query_params.method;

	query_params.tls_client_cert.s = NULL;
	query_params.tls_client_cert.len = 0;
	if (aq->query_params.tls_client_cert.s && aq->query_params.tls_client_cert.len > 0) {
		if (shm_str_dup(&query_params.tls_client_cert, &(aq->query_params.tls_client_cert)) < 0) {
			LM_ERR("Error allocating query_params.tls_client_cert\n");
			goto done;
		}
	}

	query_params.tls_client_key.s = NULL;
	query_params.tls_client_key.len = 0;
	if (aq->query_params.tls_client_key.s && aq->query_params.tls_client_key.len > 0) {
		if (shm_str_dup(&query_params.tls_client_key, &(aq->query_params.tls_client_key)) < 0) {
			LM_ERR("Error allocating query_params.tls_client_key\n");
			goto done;
		}
	}

	query_params.tls_ca_path.s = NULL;
	query_params.tls_ca_path.len = 0;
	if (aq->query_params.tls_ca_path.s && aq->query_params.tls_ca_path.len > 0) {
		if (shm_str_dup(&query_params.tls_ca_path, &(aq->query_params.tls_ca_path)) < 0) {
			LM_ERR("Error allocating query_params.tls_ca_path\n");
			goto done;
		}
	}

	query_params.body.s = NULL;
	query_params.body.len = 0;
	if (aq->query_params.body.s && aq->query_params.body.len > 0) {
		if (shm_str_dup(&query_params.body, &(aq->query_params.body)) < 0) {
			LM_ERR("Error allocating query_params.body\n");
			goto done;
		}
	}
  
	query_params.username = NULL;
	if (aq->query_params.username) {
		len = strlen(aq->query_params.username);
		query_params.username = shm_malloc(len+1);
	
		if(query_params.username == NULL) {
			LM_ERR("error in shm_malloc\n");
			goto done;
		}

		strncpy(query_params.username, aq->query_params.username, len);
		query_params.username[len] = '\0';
	}
	
	query_params.password = NULL;
	if (aq->query_params.password) {
		len = strlen(aq->query_params.password);
		query_params.password = shm_malloc(len+1);
	
		if(query_params.password == NULL) {
			LM_ERR("error in shm_malloc\n");
			goto done;
		}

		strncpy(query_params.password, aq->query_params.password, len);
		query_params.password[len] = '\0';
	}

	LM_DBG("query received: [%.*s] (%p)\n", query.len, query.s, aq);

	if (new_request(&query, &query_params, async_http_cb, aq) < 0) {
		LM_ERR("Cannot create request for %.*s\n", query.len, query.s);
		free_async_query(aq);
	}

done:
	if (query_params.tls_client_cert.s && query_params.tls_client_cert.len > 0) {
		shm_free(query_params.tls_client_cert.s);
		query_params.tls_client_cert.s = NULL;
		query_params.tls_client_cert.len = 0;
	}
	if (query_params.tls_client_key.s && query_params.tls_client_key.len > 0) {
		shm_free(query_params.tls_client_key.s);
		query_params.tls_client_key.s = NULL;
		query_params.tls_client_key.len = 0;
	}
	if (query_params.tls_ca_path.s && query_params.tls_ca_path.len > 0) {
		shm_free(query_params.tls_ca_path.s);
		query_params.tls_ca_path.s = NULL;
		query_params.tls_ca_path.len = 0;
	}
	if (query_params.body.s && query_params.body.len > 0) {
		shm_free(query_params.body.s);
		query_params.body.s = NULL;
		query_params.body.len = 0;
	}

	if (query_params.username) {
		shm_free(query_params.username);
		query_params.username = NULL;
	}
	
	if (query_params.password) {
		shm_free(query_params.password);
		query_params.password = NULL;
	}

	return;
}
Esempio n. 14
0
/*Actions are composed as follows:
 * (the action length and type as always= 5 bytes)
 * 4:uac_id
 *
 * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp)
 * TODO performance speedup: instead of using
 * dynamically allocated memory for headers,body,totag,reason and my_msg
 * use static buffers.
 *
 */
int ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
{
   unsigned int cseq;
   char err_buf[MAX_REASON_LEN];
   struct sip_msg *my_msg;
   struct to_body *fb,*tb;
   struct cseq_body *cseqb;
   struct as_uac_param *the_param;
   dlg_t *my_dlg;
   int k,retval,uac_id,sip_error,ret,err_ret;
   long clen;
   str headers,body,fake_uri;
   uac_req_t uac_r;

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

   net2hostL(uac_id,action,k);

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

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

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

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

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

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

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

   /** now undo all the fakes we have put in my_dlg*/
   /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/
   my_dlg->route_set=(rr_t *)0;
   if (ret < 0) {
      err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
      LM_ERR("failed to send the [%.*s] request\n",uac_r.method->len,uac_r.method->s);
      LM_ERR("Error on request_within %s\n",err_buf );
      if(err_ret > 0) {
	 as_action_fail_resp(uac_id,ret,err_buf,0);
      }else{
	 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
      }
      goto error;
   }
   retval=0;
   goto exit;
error:
   retval = -1;
   if(the_param)
      shm_free(the_param);
exit:
   seas_f.tmb.free_dlg(my_dlg);
   if(headers.s)
      pkg_free(headers.s);
   if(body.s)
      pkg_free(body.s);
   if(fake_uri.s)
      pkg_free(fake_uri.s);
   if(my_msg){
      if(my_msg->headers)
	 free_hdr_field_lst(my_msg->headers);
      pkg_free(my_msg);
   }
   return retval;
}
Esempio n. 15
0
/**
 * Adds a route rule to rf. prefix, rewrite_hostpart, rewrite_local_prefix,
 * rewrite_local_suffix, and comment must not contain NULL pointers.
 *
 * @param rf the current route_flags struct
 * @param prefix the whole scan prefix
 * @param max_targets the number of targets
 * @param prob the weight of the rule
 * @param rewrite_hostpart the rewrite_host of the rule
 * @param strip the strip value of the rule
 * @param rewrite_local_prefix the rewrite prefix
 * @param rewrite_local_suffix the rewrite suffix
 * @param status the status of the rule
 * @param hash_index the hash index of the rule
 * @param backup indicates if the route is backed up by another. only
                 useful if status==0, if set, it is the hash value
                 of another rule
 * @param backed_up an NULL-termintated array of hash indices of the route
                    for which this route is backup
 * @param comment a comment for the route rule
 *
 * @return 0 on success, -1 on failure
 *
 * @see add_route_to_tree()
 */
int add_route_rule(struct route_flags *rf, const str * prefix,
		int max_targets, double prob, const str * rewrite_hostpart, int strip,
		const str * rewrite_local_prefix, const str * rewrite_local_suffix,
		int status, int hash_index, int backup, int * backed_up,
		const str * comment) {
	struct route_rule * shm_rr, * prev = NULL, * tmp = NULL;
	struct route_rule_p_list * t_rl;
	int * t_bu;

	if (max_targets) {
		rf->max_targets = max_targets;
	} else {
		rf->max_targets++;
	}

	if ((shm_rr = shm_malloc(sizeof(struct route_rule))) == NULL) {
		LM_ERR("out of shared memory\n");
		return -1;
	}
	memset(shm_rr, 0, sizeof(struct route_rule));

	if (shm_str_dup(&shm_rr->host, rewrite_hostpart) != 0) {
		goto mem_error;
	}

	if (shm_str_dup(&shm_rr->prefix, prefix) != 0) {
		goto mem_error;
 	}

	shm_rr->strip = strip;

	if (shm_str_dup(&shm_rr->local_prefix, rewrite_local_prefix) != 0) {
		goto mem_error;
	}

	if (shm_str_dup(&shm_rr->local_suffix, rewrite_local_suffix) != 0) {
		goto mem_error;
	}

	if (shm_str_dup(&shm_rr->comment, comment) != 0) {
		goto mem_error;
	}

	shm_rr->status = status;
	shm_rr->hash_index = hash_index;
	shm_rr->orig_prob = prob;
	if (shm_rr->status || backup != -1) {
		shm_rr->prob = prob;
	}	else {
	    shm_rr->prob = 0;
	}
	if (backup >= 0) {
		if ((shm_rr->backup = shm_malloc(sizeof(struct route_rule_p_list))) == NULL) {
			goto mem_error;
		}
		memset(shm_rr->backup, 0, sizeof(struct route_rule_p_list));
		shm_rr->backup->hash_index = backup;
	}
	shm_rr->backed_up = NULL;
	t_bu = backed_up;
	if(!backed_up){
		LM_INFO("no backed up rules\n");
	}
	while (t_bu && *t_bu != -1) {
		if ((t_rl = shm_malloc(sizeof(struct route_rule_p_list))) == NULL) {
			goto mem_error;
		}
		memset(t_rl, 0, sizeof(struct route_rule_p_list));
		t_rl->hash_index = *t_bu;
		t_rl->next = shm_rr->backed_up;
		shm_rr->backed_up = t_rl;
		t_bu++;
	}

	/* rules with a probability of zero are always at the beginning of the list */
	tmp = rf->rule_list;
	while(tmp && tmp->prob == 0){
		prev = tmp;
		tmp = tmp->next;
	}
	/* rules with prob > 0 are sorted by hash_index */
	while(tmp && (tmp->hash_index < shm_rr->hash_index)){
		prev = tmp;
		tmp = tmp->next;
	}
	if(prev){
		shm_rr->next = prev->next;
		prev->next = shm_rr;
	} else {
		shm_rr->next = rf->rule_list;
		rf->rule_list = shm_rr;
	}

	return 0;

mem_error:
	LM_ERR("out of shared memory\n");
	destroy_route_rule(shm_rr);
	return -1;
}
Esempio n. 16
0
/*!
 * \brief Create a new contact structure
 * \param _dom domain
 * \param _aor address of record
 * \param _contact contact string
 * \param _ci contact informations
 * \return new created contact on success, 0 on failure
 */
ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact, ucontact_info_t* _ci)
{
	ucontact_t *c;

	c = (ucontact_t*)shm_malloc(sizeof(ucontact_t));
	if (!c) {
		LM_ERR("no more shm memory\n");
		return 0;
	}
	memset(c, 0, sizeof(ucontact_t));

	if (_contact->s && _contact->len > 0) {
		if (shm_str_dup( &c->c, _contact) < 0) goto error;
	}

	if (_ci->callid->s && _ci->callid->len > 0) {
		if (shm_str_dup( &c->callid, _ci->callid) < 0) goto error;
	}

	if (_ci->user_agent->s && _ci->user_agent->len > 0) {
		if (shm_str_dup( &c->user_agent, _ci->user_agent) < 0) goto error;
	}

	if (_ci->received.s && _ci->received.len > 0) {
		if (shm_str_dup( &c->received, &_ci->received) < 0) goto error;
	}

	if (_ci->path && _ci->path->len > 0) {
		if (shm_str_dup( &c->path, _ci->path) < 0) goto error;
	}

	if (_ci->ruid.s && _ci->ruid.len > 0) {
		if (shm_str_dup( &c->ruid, &_ci->ruid) < 0) goto error;
	}

	if (_ci->instance.s && _ci->instance.len > 0) {
		if (shm_str_dup( &c->instance, &_ci->instance) < 0) goto error;
	}

	c->domain = _dom;
	c->aor = _aor;
	c->expires = _ci->expires;
	c->q = _ci->q;
	c->sock = _ci->sock;
	c->cseq = _ci->cseq;
	c->state = CS_NEW;
	c->flags = _ci->flags;
	c->cflags = _ci->cflags;
	c->methods = _ci->methods;
	c->reg_id = _ci->reg_id;
	c->last_modified = _ci->last_modified;

	return c;
error:
	LM_ERR("no more shm memory\n");
	if (c->path.s) shm_free(c->path.s);
	if (c->received.s) shm_free(c->received.s);
	if (c->user_agent.s) shm_free(c->user_agent.s);
	if (c->callid.s) shm_free(c->callid.s);
	if (c->c.s) shm_free(c->c.s);
	if (c->ruid.s) shm_free(c->ruid.s);
	if (c->instance.s) shm_free(c->instance.s);
	shm_free(c);
	return 0;
}
Esempio n. 17
0
/*!
 * \brief Create a new contact structure
 * \param _dom domain
 * \param _aor address of record
 * \param _contact contact string
 * \param _ci contact informations
 * \return new created contact on success, 0 on failure
 */
ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact, ucontact_info_t* _ci) {
    ucontact_t *c;
    param_t *prev, *curr, *param;
    int first = 1;

    c = (ucontact_t*) shm_malloc(sizeof (ucontact_t));
    if (!c) {
        LM_ERR("no more shm memory\n");
        return 0;
    }
    memset(c, 0, sizeof (ucontact_t));
    
    c->lock = lock_alloc();
    c->lock = lock_init(c->lock);

    //setup callback list
    c->cbs = (struct ulcb_head_list*) shm_malloc(sizeof (struct ulcb_head_list));
    if (c->cbs == 0) {
        LM_CRIT("no more shared mem\n");
        goto error;
    }
    c->cbs->first = 0;
    c->cbs->reg_types = 0;
    
    /*Copy parameter list into shm**/
    param = _ci->params;
    while(param) {
	/*Copy first param in curr*/
	curr = shm_malloc(sizeof (param_t));
	curr->len = param->len;
	curr->type = param->type;
	curr->next = 0;
	if (shm_str_dup(&curr->body, &param->body) < 0) goto error;
	if (shm_str_dup(&curr->name, &param->name) < 0) goto error;
	
	if(first) {
	    c->params = curr;
	    first = 0;
	} else {
	    prev->next = curr;
	}
	prev = curr;
	param = param->next;
	
    }
    
    if (shm_str_dup(&c->c, _contact) < 0) goto error;
    if (shm_str_dup(&c->callid, _ci->callid) < 0) goto error;
    if (shm_str_dup(&c->user_agent, _ci->user_agent) < 0) goto error;
    if (shm_str_dup(&c->aor, _aor) < 0) goto error;
    if (shm_str_dup(&c->domain, _dom) < 0) goto error;
    
    if (_ci->received.s && _ci->received.len) {
        if (shm_str_dup(&c->received, &_ci->received) < 0) goto error;
    }
    if (_ci->path && _ci->path->len) {
        if (shm_str_dup(&c->path, _ci->path) < 0) goto error;
    }
    
    LM_DBG("generating hash based on [%.*s]\n", _contact->len, _contact->s);
    c->contact_hash = core_hash(_contact, 0, contact_list->size);
    c->ref_count = 1;
    c->expires = _ci->expires;
    c->q = _ci->q;
    c->sock = _ci->sock;
    c->cseq = _ci->cseq;
    c->flags = _ci->flags;
    c->cflags = _ci->cflags;
    c->methods = _ci->methods;
    c->last_modified = _ci->last_modified;

    return c;
error:
    LM_ERR("no more shm memory\n");
    if (c->path.s) shm_free(c->path.s);
    if (c->received.s) shm_free(c->received.s);
    if (c->user_agent.s) shm_free(c->user_agent.s);
    if (c->callid.s) shm_free(c->callid.s);
    if (c->c.s) shm_free(c->c.s);
    if (c->domain.s) shm_free(c->domain.s);
    if (c->aor.s) shm_free(c->aor.s);
    shm_free(c);
    return 0;
}