X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=common%2Ftr_config.c;h=dc6f77b0edf2cd84ffb910bd9450904bbbbdd95c;hb=3d175240ef0a8e0b465994e881ef98548a39091a;hp=4fa6506d5a15deca4adf8c24d0b0d6dd190891a8;hpb=c4274ee30f138b3851101e82383dc592b9ff655c;p=trust_router.git diff --git a/common/tr_config.c b/common/tr_config.c index 4fa6506..dc6f77b 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include @@ -174,205 +174,6 @@ TR_CFG_RC tr_apply_new_config (TR_CFG_MGR *cfg_mgr) return TR_CFG_SUCCESS; } -static TR_CFG_RC tr_cfg_parse_internal(TR_CFG *trc, json_t *jcfg) -{ - json_t *jint = NULL; - json_t *jmtd = NULL; - json_t *jtidsp = NULL; - json_t *jtrpsp = NULL; - json_t *jhname = NULL; - json_t *jlog = NULL; - json_t *jconthres = NULL; - json_t *jlogthres = NULL; - json_t *jcfgpoll = NULL; - json_t *jcfgsettle = NULL; - json_t *jroutesweep = NULL; - json_t *jrouteupdate = NULL; - json_t *jtidreq_timeout = NULL; - json_t *jtidresp_numer = NULL; - json_t *jtidresp_denom = NULL; - json_t *jrouteconnect = NULL; - - if ((!trc) || (!jcfg)) - return TR_CFG_BAD_PARAMS; - - if (NULL == trc->internal) { - if (NULL == (trc->internal = talloc_zero(trc, TR_CFG_INTERNAL))) - return TR_CFG_NOMEM; - } - - if (NULL != (jint = json_object_get(jcfg, "tr_internal"))) { - if (NULL != (jmtd = json_object_get(jint, "max_tree_depth"))) { - if (json_is_number(jmtd)) { - trc->internal->max_tree_depth = json_integer_value(jmtd); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, max_tree_depth is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* If not configured, use the default */ - trc->internal->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH; - } - if (NULL != (jtidsp = json_object_get(jint, "tids_port"))) { - if (json_is_number(jtidsp)) { - trc->internal->tids_port = json_integer_value(jtidsp); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, tids_port is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* If not configured, use the default */ - trc->internal->tids_port = TR_DEFAULT_TIDS_PORT; - } - if (NULL != (jtrpsp = json_object_get(jint, "trps_port"))) { - if (json_is_number(jtrpsp)) { - trc->internal->trps_port = json_integer_value(jtrpsp); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, trps_port is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* If not configured, use the default */ - trc->internal->trps_port = TR_DEFAULT_TRPS_PORT; - } - if (NULL != (jhname = json_object_get(jint, "hostname"))) { - if (json_is_string(jhname)) { - trc->internal->hostname = json_string_value(jhname); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, hostname is not a string."); - return TR_CFG_NOPARSE; - } - } - if (NULL != (jcfgpoll = json_object_get(jint, "cfg_poll_interval"))) { - if (json_is_number(jcfgpoll)) { - trc->internal->cfg_poll_interval = json_integer_value(jcfgpoll); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, cfg_poll_interval is not a number."); - return TR_CFG_NOPARSE; - } - } else { - trc->internal->cfg_poll_interval = TR_CFGWATCH_DEFAULT_POLL; - } - - if (NULL != (jcfgsettle = json_object_get(jint, "cfg_settling_time"))) { - if (json_is_number(jcfgsettle)) { - trc->internal->cfg_settling_time = json_integer_value(jcfgsettle); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, cfg_settling_time is not a number."); - return TR_CFG_NOPARSE; - } - } else { - trc->internal->cfg_settling_time = TR_CFGWATCH_DEFAULT_SETTLE; - } - - if (NULL != (jrouteconnect = json_object_get(jint, "trp_connect_interval"))) { - if (json_is_number(jrouteconnect)) { - trc->internal->trp_connect_interval = json_integer_value(jrouteconnect); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, trp_connect_interval is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* if not configured, use the default */ - trc->internal->trp_connect_interval=TR_DEFAULT_TRP_CONNECT_INTERVAL; - } - - if (NULL != (jroutesweep = json_object_get(jint, "trp_sweep_interval"))) { - if (json_is_number(jroutesweep)) { - trc->internal->trp_sweep_interval = json_integer_value(jroutesweep); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, trp_sweep_interval is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* if not configured, use the default */ - trc->internal->trp_sweep_interval=TR_DEFAULT_TRP_SWEEP_INTERVAL; - } - - if (NULL != (jrouteupdate = json_object_get(jint, "trp_update_interval"))) { - if (json_is_number(jrouteupdate)) { - trc->internal->trp_update_interval = json_integer_value(jrouteupdate); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, trp_update_interval is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* if not configured, use the default */ - trc->internal->trp_update_interval=TR_DEFAULT_TRP_UPDATE_INTERVAL; - } - - if (NULL != (jtidreq_timeout = json_object_get(jint, "tid_request_timeout"))) { - if (json_is_number(jtidreq_timeout)) { - trc->internal->tid_req_timeout = json_integer_value(jtidreq_timeout); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, tid_request_timeout is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* if not configured, use the default */ - trc->internal->tid_req_timeout=TR_DEFAULT_TID_REQ_TIMEOUT; - } - - if (NULL != (jtidresp_numer = json_object_get(jint, "tid_response_numerator"))) { - if (json_is_number(jtidresp_numer)) { - trc->internal->tid_resp_numer = json_integer_value(jtidresp_numer); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, tid_response_numerator is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* if not configured, use the default */ - trc->internal->tid_resp_numer=TR_DEFAULT_TID_RESP_NUMER; - } - - if (NULL != (jtidresp_denom = json_object_get(jint, "tid_response_denominator"))) { - if (json_is_number(jtidresp_denom)) { - trc->internal->tid_resp_denom = json_integer_value(jtidresp_denom); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, tid_response_denominator is not a number."); - return TR_CFG_NOPARSE; - } - } else { - /* if not configured, use the default */ - trc->internal->tid_resp_denom=TR_DEFAULT_TID_RESP_DENOM; - } - - if (NULL != (jlog = json_object_get(jint, "logging"))) { - if (NULL != (jlogthres = json_object_get(jlog, "log_threshold"))) { - if (json_is_string(jlogthres)) { - trc->internal->log_threshold = str2sev(json_string_value(jlogthres)); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, log_threshold is not a string."); - return TR_CFG_NOPARSE; - } - } else { - /* If not configured, use the default */ - trc->internal->log_threshold = TR_DEFAULT_LOG_THRESHOLD; - } - - if (NULL != (jconthres = json_object_get(jlog, "console_threshold"))) { - if (json_is_string(jconthres)) { - trc->internal->console_threshold = str2sev(json_string_value(jconthres)); - } else { - tr_debug("tr_cfg_parse_internal: Parsing error, console_threshold is not a string."); - return TR_CFG_NOPARSE; - } - } else { - /* If not configured, use the default */ - trc->internal->console_threshold = TR_DEFAULT_CONSOLE_THRESHOLD; - } - } else { - /* If not configured, use the default */ - trc->internal->console_threshold = TR_DEFAULT_CONSOLE_THRESHOLD; - trc->internal->log_threshold = TR_DEFAULT_LOG_THRESHOLD; - } - - tr_debug("tr_cfg_parse_internal: Internal config parsed."); - return TR_CFG_SUCCESS; - } - return TR_CFG_SUCCESS; -} - static TR_CONSTRAINT *tr_cfg_parse_one_constraint(TALLOC_CTX *mem_ctx, char *ctype, json_t *jc, TR_CFG_RC *rc) { TR_CONSTRAINT *cons=NULL; @@ -1460,60 +1261,6 @@ static TR_NAME *tr_cfg_parse_org_name(TALLOC_CTX *mem_ctx, json_t *j_org, TR_CFG return name; } -#if 0 -/* TODO: are we using this? JLR */ -/* Update the community information with data from a new batch of IDP realms. - * May partially add realms if there is a failure, no guarantees. - * Call like comms=tr_comm_idp_update(comms, new_realms, &rc) */ -static TR_COMM *tr_cfg_comm_idp_update(TALLOC_CTX *mem_ctx, - TR_COMM_TABLE *ctab, - TR_IDP_REALM *new_realms, - TR_CFG_RC *rc) -{ - TALLOC_CTX *tmp_ctx=talloc_new(NULL); - TR_COMM *comm=NULL; /* community looked up in comms table */ - TR_COMM *new_comms=NULL; /* new communities as we create them */ - TR_IDP_REALM *realm=NULL; - TR_APC *apc=NULL; /* apc of one realm */ - - if (rc==NULL) { - *rc=TR_CFG_BAD_PARAMS; - goto cleanup; - } - - /* start with an empty list communities, then fill that in */ - for (realm=new_realms; realm!=NULL; realm=realm->next) { - for (apc=realm->apcs; apc!=NULL; apc=apc->next) { - comm=tr_comm_lookup(comms, apc->id); - if (comm==NULL) { - comm=tr_comm_new(tmp_ctx); - if (comm==NULL) { - tr_debug("tr_cfg_comm_idp_update: unable to allocate new community."); - *rc=TR_CFG_NOMEM; - goto cleanup; - } - /* fill in the community with info */ - comm->type=TR_COMM_APC; /* realms added this way are in APCs */ - comm->expiration_interval=TR_DEFAULT_APC_EXPIRATION_INTERVAL; - tr_comm_set_id(comm, tr_dup_name(apc->id)); - tr_comm_add_idp_realm(comm, realm); - tr_comm_add(new_comms, comm); - } else { - /* add this realm to the comm */ - tr_comm_add_idp_realm(comm, realm); - } - } - } - - /* we successfully built a list, add it to the other list */ - tr_comm_add(comms, new_comms); - talloc_steal(mem_ctx, comms); - cleanup: - talloc_free(tmp_ctx); - return comms; -} -#endif - static TR_CFG_RC tr_cfg_parse_one_local_org(TR_CFG *trc, json_t *jlorg) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); @@ -1650,7 +1397,7 @@ static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg) goto cleanup; } - trp_peer_set_server(new_peer, json_string_value(jhost)); + trp_peer_set_server(new_peer, json_string_value(jhost)); /* string is strdup'ed in _set_server() */ if (jport==NULL) trp_peer_set_port(new_peer, TRP_PORT); else @@ -2019,13 +1766,6 @@ TR_CFG_RC tr_cfg_validate(TR_CFG *trc) return rc; } -/* Join two paths and return a pointer to the result. This should be freed - * via talloc_free. Returns NULL on failure. */ -static char *join_paths(TALLOC_CTX *mem_ctx, const char *p1, const char *p2) -{ - return talloc_asprintf(mem_ctx, "%s/%s", p1, p2); /* returns NULL on a failure */ -} - static void tr_cfg_log_json_error(const char *label, json_error_t *rc) { tr_debug("%s: JSON parse error on line %d: %s", @@ -2034,7 +1774,14 @@ static void tr_cfg_log_json_error(const char *label, json_error_t *rc) rc->text); } -TR_CFG_RC tr_cfg_parse_one_config_file(TR_CFG *cfg, const char *file_with_path) +/** + * Parse a config file and return its JSON structure. Also emits a serial number to the log + * if one is present. + * + * @param file_with_path The file (with path!) to parse + * @return Pointer to the result of parsing, or null on error + */ +static json_t *tr_cfg_parse_one_config_file(const char *file_with_path) { json_t *jcfg=NULL; json_t *jser=NULL; @@ -2045,10 +1792,10 @@ TR_CFG_RC tr_cfg_parse_one_config_file(TR_CFG *cfg, const char *file_with_path) tr_debug("tr_cfg_parse_one_config_file: Error parsing config file %s.", file_with_path); tr_cfg_log_json_error("tr_cfg_parse_one_config_file", &rc); - return TR_CFG_NOPARSE; + return NULL; } - // Look for serial number and log it if it exists + // Look for serial number and log it if it exists (borrowed reference, so no need to free it later) if (NULL!=(jser=json_object_get(jcfg, "serial_number"))) { if (json_is_number(jser)) { tr_notice("tr_parse_one_config_file: Attempting to load revision %" JSON_INTEGER_FORMAT " of '%s'.", @@ -2057,29 +1804,122 @@ TR_CFG_RC tr_cfg_parse_one_config_file(TR_CFG *cfg, const char *file_with_path) } } - if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(cfg, jcfg)) || - (TR_CFG_SUCCESS != tr_cfg_parse_local_orgs(cfg, jcfg)) || - (TR_CFG_SUCCESS != tr_cfg_parse_peer_orgs(cfg, jcfg)) || - (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(cfg, jcfg)) || - (TR_CFG_SUCCESS != tr_cfg_parse_comms(cfg, jcfg))) + return jcfg; +} + +/** + * Helper to free an array returned by tr_cfg_parse_config_files + * @param n_jcfgs + * @param jcfgs + */ +static void tr_cfg_parse_free_jcfgs(unsigned int n_jcfgs, json_t **jcfgs) +{ + int ii=0; + for (ii=0; iinew != NULL) tr_cfg_free(cfg_mgr->new); cfg_mgr->new=tr_cfg_new(tmp_ctx); /* belongs to the temporary context for now */ @@ -2088,25 +1928,24 @@ TR_CFG_RC tr_parse_config(TR_CFG_MGR *cfg_mgr, const char *config_dir, int n, st goto cleanup; } - cfg_mgr->new->peers=trp_ptable_new(cfg_mgr); - - /* Parse configuration information from each config file */ - for (ii=0; iid_name); /* must free result with talloc_free */ - if(file_with_path == NULL) { - tr_crit("tr_parse_config: error joining path."); - cfg_rc=TR_CFG_NOMEM; - goto cleanup; - } - tr_debug("tr_parse_config: Parsing %s.", cfg_files[ii]->d_name); /* print the filename without the path */ - cfg_rc=tr_cfg_parse_one_config_file(cfg_mgr->new, file_with_path); - if (cfg_rc!=TR_CFG_SUCCESS) { - tr_crit("tr_parse_config: Error parsing %s", file_with_path); - goto cleanup; - } - talloc_free(file_with_path); /* done with filename */ + /* first parse the json */ + jcfgs=tr_cfg_parse_config_files(tmp_ctx, n_files, files_with_paths); + if (jcfgs==NULL) { + cfg_rc=TR_CFG_NOPARSE; + goto cleanup; } + cfg_mgr->new->peers=trp_ptable_new(cfg_mgr); /* not sure why this isn't in cfg_mgr->new's context */ + + /* now run through the parsers on the JSON */ + if ((TR_CFG_SUCCESS != (cfg_rc= tr_cfg_parse_helper(cfg_mgr->new, tr_cfg_parse_internal, n_files, jcfgs, "tr_internal"))) || + (TR_CFG_SUCCESS != (cfg_rc= tr_cfg_parse_helper(cfg_mgr->new, tr_cfg_parse_local_orgs, n_files, jcfgs, NULL))) || + (TR_CFG_SUCCESS != (cfg_rc= tr_cfg_parse_helper(cfg_mgr->new, tr_cfg_parse_peer_orgs, n_files, jcfgs, NULL))) || + (TR_CFG_SUCCESS != (cfg_rc= tr_cfg_parse_helper(cfg_mgr->new, tr_cfg_parse_default_servers, n_files, jcfgs, + NULL))) || + (TR_CFG_SUCCESS != (cfg_rc= tr_cfg_parse_helper(cfg_mgr->new, tr_cfg_parse_comms, n_files, jcfgs, NULL)))) + goto cleanup; /* cfg_rc was set above */ + /* make sure we got a complete, consistent configuration */ if (TR_CFG_SUCCESS != tr_cfg_validate(cfg_mgr->new)) { tr_err("tr_parse_config: Error: INVALID CONFIGURATION"); @@ -2119,6 +1958,8 @@ TR_CFG_RC tr_parse_config(TR_CFG_MGR *cfg_mgr, const char *config_dir, int n, st cfg_rc=TR_CFG_SUCCESS; cleanup: + if (jcfgs!=NULL) + tr_cfg_parse_free_jcfgs(n_files, jcfgs); talloc_free(tmp_ctx); return cfg_rc; } @@ -2197,7 +2038,7 @@ static int is_cfg_file(const struct dirent *dent) { * allocated array of pointers to struct dirent entries, as returned * by scandir(). These can be freed with tr_free_config_file_list(). */ -int tr_find_config_files (const char *config_dir, struct dirent ***cfg_files) { +int tr_find_config_files(const char *config_dir, struct dirent ***cfg_files) { int n = 0; n = scandir(config_dir, cfg_files, is_cfg_file, alphasort);