Example #1
0
void receive_prof_repl(bin_packet_t *packet)
{
	time_t now;
	str name;
	str value;
	unsigned int counter;
	struct dlg_profile_table *profile;
	int has_value;
	int i;
	void **dst;
	prof_value_info_t *rp;
	repl_prof_count_t *destination;

	/* optimize profile search */
	struct dlg_profile_table *old_profile = NULL;
	str old_name = {NULL,0};

	if (!profile_repl_cluster)
		return;

	if (packet->type != REPLICATION_DLG_PROFILE) {
		LM_WARN("Invalid dialog binary packet command: %d (from node: %d in cluster: %d)\n",
			packet->type, packet->src_id, profile_repl_cluster);
		return;
	}

	now = time(0);
	//*repl_prof_dests[index].last_msg = now;

	for (;;) {
		if (bin_pop_str(packet ,&name) == 1)
			break; /* pop'ed all pipes */

		/* check if the same profile was sent */
		if (!old_profile || old_name.len != name.len ||
			memcmp(name.s, old_name.s, name.len) != 0) {
			old_profile = get_dlg_profile(&name);
			if (!old_profile)
				LM_WARN("received unknown profile <%.*s> from node %d\n",
					name.len, name.s, packet->src_id);
			old_name = name;
		}
		profile = old_profile;

		if (bin_pop_int(packet, &has_value) < 0) {
			LM_ERR("cannot pop profile's has_value int\n");
			return;
		}

		if (has_value) {
			if (!profile->has_value) {
				LM_WARN("The other end does not have a value for this profile:"
					"<%.*s> [node: %d]\n", profile->name.len, profile->name.s,
					packet->src_id);
				profile = NULL;
			}
			if (bin_pop_str(packet, &value)) {
				LM_ERR("cannot pop the value of the profile\n");
				return;
			}
		}

		if (bin_pop_int(packet, &counter) < 0) {
			LM_ERR("cannot pop profile's counter\n");
			return;
		}

		if (profile) {
			if (!profile->has_value) {
				lock_get(&profile->noval_repl_info->lock);
				destination = find_destination(profile->noval_repl_info, packet->src_id);
				if(destination == NULL){
					lock_release(&profile->noval_repl_info->lock);
					return;
				}
				destination->counter = counter;
				destination->update = now;
				lock_release(&profile->noval_repl_info->lock);
			} else {
				/* XXX: hack to make sure we find the proper index */
				i = core_hash(&value, NULL, profile->size);
				lock_set_get(profile->locks, i);
				/* if counter is 0 and we don't have it, don't try to create */
				if (!counter) {
					dst = map_find(profile->entries[i], value);
					if (!dst)
						goto release;
				} else {
					dst = map_get(profile->entries[i], value);
				}
				if (!*dst) {
					rp = shm_malloc(sizeof(prof_value_info_t));
					if (!rp) {
						LM_ERR("no more shm memory to allocate repl_prof_value\n");
						goto release;
					}
					memset(rp, 0, sizeof(prof_value_info_t));
					*dst = rp;
				} else {
					rp = (prof_value_info_t *) * dst;
				}
				if (!rp->noval)
					rp->noval = repl_prof_allocate();
				if (rp->noval) {
					lock_release(&rp->noval->lock);
					destination = find_destination(rp->noval, packet->src_id);
					if (destination == NULL) {
						lock_release(&rp->noval->lock);
						lock_set_release(profile->locks, i);
						return;
					}
					destination->counter = counter;
					destination ->update = now;
					lock_release(&rp->noval->lock);
				}
release:
				lock_set_release(profile->locks, i);
			}
		}
	}
	return;
}
Example #2
0
void rl_rcv_bin(bin_packet_t *packet)
{
	rl_algo_t algo;
	int limit;
	int counter;
	str name;
	rl_pipe_t **pipe;
	unsigned int hash_idx;
	time_t now;
	rl_repl_counter_t *destination;

	if (packet->type != RL_PIPE_COUNTER) {
		LM_WARN("Invalid binary packet command: %d (from node: %d in cluster: %d)\n",
			packet->type, packet->src_id, rl_repl_cluster);
		return;
	}

	now = time(0);

	for (;;) {
		if (bin_pop_str(packet, &name) == 1)
			break; /* pop'ed all pipes */

		if (bin_pop_int(packet, &algo) < 0) {
			LM_ERR("cannot pop pipe's algorithm\n");
			return;
		}

		if (bin_pop_int(packet, &limit) < 0) {
			LM_ERR("cannot pop pipe's limit\n");
			return;
		}

		if (bin_pop_int(packet, &counter) < 0) {
			LM_ERR("cannot pop pipe's counter\n");
			return;
		}

		hash_idx = RL_GET_INDEX(name);
		RL_GET_LOCK(hash_idx);

		/* try to get the value */
		pipe = RL_GET_PIPE(hash_idx, name);
		if (!pipe) {
			LM_ERR("cannot get the index\n");
			goto release;
		}

		if (!*pipe) {
			/* if the pipe does not exist, allocate it in case we need it later */
			if (!(*pipe = rl_create_pipe(limit, algo)))
				goto release;
			LM_DBG("Pipe %.*s doesn't exist, but was created %p\n",
				name.len, name.s, *pipe);

		} else {
			LM_DBG("Pipe %.*s found: %p - last used %lu\n",
				name.len, name.s, *pipe, (*pipe)->last_used);
			if ((*pipe)->algo != algo)
				LM_WARN("algorithm %d different from the initial one %d for "
				"pipe %.*s", algo, (*pipe)->algo, name.len, name.s);
			/*
			 * XXX: do not output these warnings since they can be triggered
			 * when a custom limit is used
			if ((*pipe)->limit != limit)
				LM_WARN("limit %d different from the initial one %d for "
				"pipe %.*s", limit, (*pipe)->limit, name.len, name.s);
			 */
		}
		/* set the last used time */
		(*pipe)->last_used = time(0);
		/* set the destination's counter */
		destination = find_destination(*pipe, packet->src_id);
		if (!destination)
			goto release;
		destination->counter = counter;
		destination->update = now;
		RL_RELEASE_LOCK(hash_idx);
	}
	return;

release:
	RL_RELEASE_LOCK(hash_idx);
}
Example #3
0
void rl_rcv_bin(int packet_type, struct receive_info *ri, int server_id)
{
	rl_algo_t algo;
	int limit;
	int counter;
	str name;
	char *ip;
	unsigned short port;
	rl_pipe_t **pipe;
	unsigned int hash_idx;
	time_t now;
	rl_repl_counter_t *destination;
	
	if (packet_type == SERVER_TEMP_DISABLED) {
 		get_su_info(&ri->src_su.s, ip, port);
		LM_WARN("server: %s:%hu temporary disabled\n", ip, port);
 		return;
 	}

	if (packet_type == SERVER_TIMEOUT) {
		LM_WARN("server with clustererer id %d timeout\n", server_id);
		return;
	}
	
	if(get_bin_pkg_version() != BIN_VERSION){
		LM_ERR("incompatible bin protocol version\n");
		return;
	}

	if (packet_type != RL_PIPE_COUNTER)
		return;

	if (packet_type != RL_PIPE_COUNTER)
		return;

	now = time(0);

	for (;;) {
		if (bin_pop_str(&name) == 1)
			break; /* pop'ed all pipes */

		if (bin_pop_int(&algo) < 0) {
			LM_ERR("cannot pop pipe's algorithm\n");
			return;
		}

		if (bin_pop_int(&limit) < 0) {
			LM_ERR("cannot pop pipe's limit\n");
			return;
		}

		if (bin_pop_int(&counter) < 0) {
			LM_ERR("cannot pop pipe's counter\n");
			return;
		}

		hash_idx = RL_GET_INDEX(name);
		RL_GET_LOCK(hash_idx);

		/* try to get the value */
		pipe = RL_GET_PIPE(hash_idx, name);
		if (!pipe) {
			LM_ERR("cannot get the index\n");
			goto release;
		}

		if (!*pipe) {
			/* if the pipe does not exist, alocate it in case we need it later */
			*pipe = shm_malloc(sizeof(rl_pipe_t));
			if (!*pipe) {
				LM_ERR("no more shm memory\n");
				goto release;
			}
			memset(*pipe, 0, sizeof(rl_pipe_t));
			LM_DBG("Pipe %.*s doesn't exist, but was created %p\n",
				name.len, name.s, *pipe);
			(*pipe)->algo = algo;
			(*pipe)->limit = limit;
		} else {
			LM_DBG("Pipe %.*s found: %p - last used %lu\n",
				name.len, name.s, *pipe, (*pipe)->last_used);
			if ((*pipe)->algo != algo)
				LM_WARN("algorithm %d different from the initial one %d for "
				"pipe %.*s", algo, (*pipe)->algo, name.len, name.s);
			if ((*pipe)->limit != limit)
				LM_WARN("limit %d different from the initial one %d for "
				"pipe %.*s", limit, (*pipe)->limit, name.len, name.s);
		}
		/* set the last used time */
		(*pipe)->last_used = time(0);
		/* set the destination's counter */
		destination = find_destination(*pipe, server_id);
		destination->counter = counter;
		destination->update = now;
		RL_RELEASE_LOCK(hash_idx);
	}
	return;

release:
	RL_RELEASE_LOCK(hash_idx);
}
Example #4
0
static void dlg_replicated_profiles(struct receive_info *ri, int server_id)
{
	time_t now;
	str name;
	str value;
	char *ip;
	unsigned short port;
	unsigned int counter;
	struct dlg_profile_table *profile;
	int has_value;
	int i;
	void **dst;
	repl_prof_value_t *rp;
	repl_prof_count_t *destination;


	/* optimize profile search */
	struct dlg_profile_table *old_profile = NULL;
	str old_name;

	now = time(0);
	//*repl_prof_dests[index].last_msg = now;

	for (;;) {
		if (bin_pop_str(&name) == 1)
			break; /* pop'ed all pipes */

		/* check if the same profile was sent */
		if (!old_profile || old_name.len != name.len ||
			memcmp(name.s, old_name.s, name.len) != 0) {
			old_profile = get_dlg_profile(&name);
			if (!old_profile) {
				get_su_info(&ri->src_su.s, ip, port);
				LM_WARN("received unknown profile <%.*s> from %s:%hu\n",
					name.len, name.s, ip, port);
			}
			old_name = name;
		}
		profile = old_profile;

		if (bin_pop_int(&has_value) < 0) {
			LM_ERR("cannot pop profile's has_value int\n");
			return;
		}

		if (has_value) {
			if (!profile->has_value) {
				get_su_info(&ri->src_su.s, ip, port);
				LM_WARN("The other end does not have a value for this profile:"
					"<%.*s> [%s:%hu]\n", profile->name.len, profile->name.s, ip, port);
				profile = NULL;
			}
			if (bin_pop_str(&value)) {
				LM_ERR("cannot pop the value of the profile\n");
				return;
			}
		}

		if (bin_pop_int(&counter) < 0) {
			LM_ERR("cannot pop profile's counter\n");
			return;
		}

		if (profile) {
			if (!profile->has_value) {
				lock_get(&profile->repl->lock);
				destination = find_destination(profile->repl, server_id);
				if(destination == NULL){
					lock_release(&profile->repl->lock);
					return;
				}
				destination->counter = counter;
				destination->update = now;
				lock_release(&profile->repl->lock);
			} else {
				/* XXX: hack to make sure we find the proper index */
				i = core_hash(&value, NULL, profile->size);
				lock_set_get(profile->locks, i);
				/* if counter is 0 and we don't have it, don't try to create */
				if (!counter) {
					dst = map_find(profile->entries[i], value);
					if (!dst)
						goto release;
				} else {
					dst = map_get(profile->entries[i], value);
				}
				if (!*dst) {
					rp = shm_malloc(sizeof(repl_prof_value_t));
					if (!rp) {
						LM_ERR("no more shm memory to allocate repl_prof_value\n");
						goto release;
					}
					memset(rp, 0, sizeof(repl_prof_value_t));
					*dst = rp;
				} else {
					rp = (repl_prof_value_t *) * dst;
				}
				if (!rp->noval)
					rp->noval = repl_prof_allocate();
				if (rp->noval) {
					lock_release(&rp->noval->lock);
					destination = find_destination(rp->noval, server_id);
					if (destination == NULL) {
						lock_release(&rp->noval->lock);
						lock_set_release(profile->locks, i);
						return;
					}
					destination->counter = counter;
					destination ->update = now;
					lock_release(&rp->noval->lock);
				}
release:
				lock_set_release(profile->locks, i);
			}
		}
	}
	return;
}
Example #5
0
void rl_rcv_bin(int packet_type, struct receive_info *ri)
{
	rl_algo_t algo;
	int limit;
	int counter;
	int rc;
	int server_id;
	str name;
	char *ip;
	unsigned short port;
	rl_pipe_t **pipe;
	unsigned int hash_idx;
	time_t now;
	rl_repl_counter_t *destination;

	LM_DBG("received a binary packet [%d]!\n", packet_type);
	
	if (packet_type != RL_PIPE_COUNTER)
		return;
	
	rc = bin_pop_int(&server_id);
	if (rc < 0)
		return;
	
	if (!clusterer_api.check(accept_repl_pipes, &ri->src_su, server_id, ri->proto)){
		get_su_info(&ri->src_su.s, ip, port);
		LM_WARN("received bin packet from unknown source: %s:%hu\n",
				ip, port);
		return;
	}
	now = time(0);

	for (;;) {
		if (bin_pop_str(&name) == 1)
			break; /* pop'ed all pipes */

		if (bin_pop_int(&algo) < 0) {
			LM_ERR("cannot pop pipe's algorithm\n");
			return;
		}

		if (bin_pop_int(&limit) < 0) {
			LM_ERR("cannot pop pipe's limit\n");
			return;
		}

		if (bin_pop_int(&counter) < 0) {
			LM_ERR("cannot pop pipe's counter\n");
			return;
		}

		hash_idx = RL_GET_INDEX(name);
		RL_GET_LOCK(hash_idx);

		/* try to get the value */
		pipe = RL_GET_PIPE(hash_idx, name);
		if (!pipe) {
			LM_ERR("cannot get the index\n");
			goto release;
		}

		if (!*pipe) {
			/* if the pipe does not exist, alocate it in case we need it later */
			*pipe = shm_malloc(sizeof(rl_pipe_t));
			if (!*pipe) {
				LM_ERR("no more shm memory\n");
				goto release;
			}
			memset(*pipe, 0, sizeof(rl_pipe_t));
			LM_DBG("Pipe %.*s doesn't exist, but was created %p\n",
					name.len, name.s, *pipe);
			(*pipe)->algo = algo;
			(*pipe)->limit = limit;
		} else {
			LM_DBG("Pipe %.*s found: %p - last used %lu\n",
					name.len, name.s, *pipe, (*pipe)->last_used);
			if ((*pipe)->algo != algo)
				LM_WARN("algorithm %d different from the initial one %d for "
						"pipe %.*s", algo, (*pipe)->algo, name.len, name.s);
			if ((*pipe)->limit != limit)
				LM_WARN("limit %d different from the initial one %d for "
						"pipe %.*s", limit, (*pipe)->limit, name.len, name.s);
		}
		/* set the last used time */
		(*pipe)->last_used = time(0);
		/* set the destination's counter */
		destination = find_destination(*pipe, server_id);
		destination->counter = counter;
		destination->update = now;
		RL_RELEASE_LOCK(hash_idx);
	}
	return;

release:
	RL_RELEASE_LOCK(hash_idx);
}