Exemple #1
0
/**
 * loads the config data into shared memory (but doesn't really
 * share it), updates the routing data and writes it to the config
 * file. Afterwards, the global routing data is reloaded.
 *
 * @param opts pointer to the option structure which contains
 * data to be modified or to be added
 *
 * @return 0 on success, -1 on failure
 */
static int update_route_data(fifo_opt_t * opts) {
	struct rewrite_data * rd;
	int i,j;
	str tmp_domain;
	str tmp_prefix;
	str tmp_host;
	str tmp_rewrite_prefix;
	str tmp_rewrite_suffix;
	str tmp_comment = str_init("");

	if ((rd = shm_malloc(sizeof(struct rewrite_data))) == NULL) {
		LM_ERR("out of shared memory\n");
		return -1;
	}
	memset(rd, 0, sizeof(struct rewrite_data));
	if (load_config(rd) < 0) {
		LM_ERR("could not load config\n");
		FIFO_ERR(E_LOADCONF);
		return -1;
	}

	if (rule_fixup(rd) < 0) {
		LM_ERR("could not fixup rules\n");
		FIFO_ERR(E_RULEFIXUP);
		return -1;
	}
	updated = 0;

	if (opts->cmd == OPT_ADD) {
		tmp_domain=opts->domain;
		tmp_prefix=opts->prefix;
		tmp_host=opts->host;
		tmp_rewrite_prefix=opts->rewrite_prefix;
		tmp_rewrite_suffix=opts->rewrite_suffix;
		if (tmp_domain.s==NULL) {
			tmp_domain.s="";
			tmp_domain.len=0;
		}
		if (tmp_prefix.s==NULL) {
			tmp_prefix.s="";
			tmp_prefix.len=0;
		}
		if (tmp_host.s==NULL) {
			tmp_host.s="";
			tmp_host.len=0;
		}
		if (tmp_rewrite_prefix.s==NULL) {
			tmp_rewrite_prefix.s="";
			tmp_rewrite_prefix.len=0;
		}
		if (tmp_rewrite_suffix.s==NULL) {
			tmp_rewrite_suffix.s="";
			tmp_rewrite_suffix.len=0;
		}

		if (add_route(rd, 1, &tmp_domain, &tmp_prefix, 0, 0, 0, opts->prob,
		              &tmp_host, opts->strip, &tmp_rewrite_prefix, &tmp_rewrite_suffix,
		              opts->status, opts->hash_index, -1, NULL, &tmp_comment) < 0) {
			goto errout;
		}
		updated = 1;
		if (rule_fixup(rd) < 0) {
			LM_ERR("could not fixup rules after route appending\n");
			FIFO_ERR(E_RULEFIXUP);
			return -1;
		}

	} else {
		for (i=0; i<rd->tree_num; i++) {
			if(rd->carriers[i]){
			for (j=0; j<rd->carriers[i]->tree_num; j++) {
				if (rd->carriers[i]->trees[j] && rd->carriers[i]->trees[j]->tree) {
					if (update_route_data_recursor(rd->carriers[i]->trees[j]->tree, &rd->carriers[i]->trees[j]->name, opts) < 0) {
						goto errout;
					}
				}
			}
			}
		}
	}

	if(!updated){
		LM_ERR("no match for update found\n");
		FIFO_ERR(E_NOUPDATE);
		goto errout;
	}

	if (save_config(rd) < 0) {
		LM_ERR("could not save config\n");
		FIFO_ERR(E_SAVECONF);
		goto errout;
	}

	if (prepare_route_tree() == -1) {
		LM_ERR("could not prepare the route tree\n");
		FIFO_ERR(E_LOADCONF);
		goto errout;
	}

	destroy_rewrite_data(rd);
	return 0;
errout:
	destroy_rewrite_data(rd);
	return -1;
}
Exemple #2
0
/**
 * loads the config data into shared memory (but doesn't really
 * share it), updates the routing data and writes it to the config
 * file. Afterwards, the global routing data is reloaded.
 *
 * @param opts pointer to the option structure which contains
 * data to be modified or to be added
 *
 * @return 0 on success, -1 on failure
 */
static int update_route_data(fifo_opt_t * opts) {
	struct route_data_t * rd;
	int i,j;
	int domain_id;
	str tmp_domain;
	str tmp_prefix;
	str tmp_host;
	str tmp_rewrite_prefix;
	str tmp_rewrite_suffix;
	str tmp_comment = str_init("");

	if ((rd = shm_malloc(sizeof(struct route_data_t))) == NULL) {
		SHM_MEM_ERROR;
		return -1;
	}
	memset(rd, 0, sizeof(struct route_data_t));
	if (load_config(rd) < 0) {
		LM_ERR("could not load config");
		FIFO_ERR(E_LOADCONF);
		return -1;
	}

	if (rule_fixup(rd) < 0) {
		LM_ERR("could not fixup rules");
		FIFO_ERR(E_RULEFIXUP);
		return -1;
	}
	updated = 0;

	if (opts->cmd == OPT_ADD) {
		tmp_domain=opts->domain;
		tmp_prefix=opts->prefix;
		tmp_host=opts->host;
		tmp_rewrite_prefix=opts->rewrite_prefix;
		tmp_rewrite_suffix=opts->rewrite_suffix;
		if (tmp_domain.s==NULL) {
			tmp_domain.s="";
			tmp_domain.len=0;
		}
		if (tmp_prefix.s==NULL) {
			tmp_prefix.s="";
			tmp_prefix.len=0;
		}
		if (tmp_host.s==NULL) {
			tmp_host.s="";
			tmp_host.len=0;
		}
		if (tmp_rewrite_prefix.s==NULL) {
			tmp_rewrite_prefix.s="";
			tmp_rewrite_prefix.len=0;
		}
		if (tmp_rewrite_suffix.s==NULL) {
			tmp_rewrite_suffix.s="";
			tmp_rewrite_suffix.len=0;
		}

		domain_id = map_name2id(rd->domain_map, rd->domain_num, &tmp_domain);
		if (domain_id < 0) {
			LM_ERR("cannot find id for domain '%.*s'", tmp_domain.len, tmp_domain.s);
			goto errout;
		}

		if (add_route(rd, 1, domain_id, &tmp_prefix, 0, 0, 0, opts->prob,
		              &tmp_host, opts->strip, &tmp_rewrite_prefix, &tmp_rewrite_suffix,
		              opts->status, opts->hash_index, -1, NULL, &tmp_comment) < 0) {
			goto errout;
		}
		updated = 1;
		if (rule_fixup(rd) < 0) {
			LM_ERR("could not fixup rules after route appending");
			FIFO_ERR(E_RULEFIXUP);
			goto errout;
		}
	} else {
		for (i=0; i<rd->carrier_num; i++) {
			if(rd->carriers[i]){
				for (j=0; j<rd->carriers[i]->domain_num; j++) {
					if (rd->carriers[i]->domains[j] && rd->carriers[i]->domains[j]->tree) {
						if (update_route_data_recursor(rd->carriers[i]->domains[j]->tree, rd->carriers[i]->domains[j]->name, opts) < 0) {
							goto errout;
						}
					}
				}
			}
		}
	}

	if(!updated){
		LM_ERR("no match for update found");
		FIFO_ERR(E_NOUPDATE);
		goto errout;
	}

	if (save_config(rd) < 0) {
		LM_ERR("could not save config");
		FIFO_ERR(E_SAVECONF);
		goto errout;
	}

	if (reload_route_data() == -1) {
		LM_ERR("could not reload route data");
		FIFO_ERR(E_LOADCONF);
		goto errout;
	}

	clear_route_data(rd);
	return 0;
errout:
	clear_route_data(rd);
	return -1;
}
Exemple #3
0
/**
 * Loads the routing data into the routing trees and sets the
 * global_data pointer to the new data. The old_data is removed
 * when it is not locked anymore.
 *
 * @return 0 on success, -1 on failure
 */
int reload_route_data(void) {
	struct route_data_t * old_data;
	struct route_data_t * new_data = NULL;
	int i;

	if ((new_data = shm_malloc(sizeof(struct route_data_t))) == NULL) {
		SHM_MEM_ERROR;
		return -1;
	}
	memset(new_data, 0, sizeof(struct route_data_t));

	switch (mode) {
	case CARRIERROUTE_MODE_DB:
		if (load_route_data_db(new_data) < 0) {
			LM_ERR("could not load routing data\n");
			goto errout;
		}
		break;
	case CARRIERROUTE_MODE_FILE:
		if (load_config(new_data) < 0) {
			LM_ERR("could not load routing data\n");
			goto errout;
		}
		break;
	default:
		LM_ERR("invalid mode");
		goto errout;
	}
	if (new_data == NULL) {
		LM_ERR("loading routing data failed (NULL pointer)");
		goto errout;
	}

	/* sort carriers by id for faster access */
	qsort(new_data->carriers, new_data->carrier_num, sizeof(new_data->carriers[0]), compare_carrier_data);

	/* sort domains by id for faster access */
	for (i=0; i<new_data->carrier_num; i++) {
		qsort(new_data->carriers[i]->domains, new_data->carriers[i]->domain_num, sizeof(new_data->carriers[i]->domains[0]), compare_domain_data);
	}

	if (rule_fixup(new_data) < 0) {
		LM_ERR("could not fixup rules\n");
		goto errout;
	}

	if (carrier_data_fixup(new_data) < 0){
		LM_ERR("could not fixup trees\n");
		goto errout;
	}

	new_data->proc_cnt = 0;

	if (*global_data == NULL) {
		*global_data = new_data;
	} else {
		old_data = *global_data;
		*global_data = new_data;
		i = 0;
		while (old_data->proc_cnt > 0) {
			LM_ERR("data is still locked after %i seconds\n", i);
			sleep_us(i*1000000);
			i++;
		}
		clear_route_data(old_data);
	}
	return 0;

 errout:
	clear_route_data(new_data);
	return -1;
}