From f52f20507c568db42dbd2ddc99c7fa5a27012868 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Tue, 23 Aug 2016 17:12:51 -0400 Subject: [PATCH] Peer organizations now parsed and added to peer table. This is feature completeness for initial Dynamic Trust Router release, not yet debugged. --- Makefile.am | 4 ++ common/tr_config.c | 153 +++++++++++++++++++++++++++++++++++++++---------- common/tr_filter.c | 5 +- common/tr_rp.c | 31 ++-------- include/tr_config.h | 2 + include/tr_rp.h | 5 +- include/trp_internal.h | 1 + include/trp_ptable.h | 17 +++--- tr/tr_main.c | 4 +- tr/tr_trp.c | 4 +- trp/trp_ptable.c | 79 +++++++++++++++++-------- trp/trps.c | 62 +++++++++++++------- 12 files changed, 254 insertions(+), 113 deletions(-) diff --git a/Makefile.am b/Makefile.am index 090034e..d509db5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,7 @@ common/tr_comm.c \ common/tr_filter.c \ common/tr_rp.c \ common/tr_mq.c \ +common/tr_gss.c \ tr/tr.c \ tr/tr_event.c \ tr/tr_cfgwatch.c \ @@ -74,6 +75,7 @@ tid/tid_req.c \ tid/tid_resp.c \ common/tr_msg.c \ common/tr_name.c \ +common/tr_gss.c \ common/tr_idp.c \ common/tr_apc.c \ common/tr_comm.c \ @@ -86,6 +88,7 @@ trp_msgtst_LDADD = $(GLIB_LIBS) trp_test_rtbl_test_SOURCES = trp/test/rtbl_test.c \ common/tr_name.c \ +common/tr_gss.c \ common/tr_debug.c \ trp/trp_rtable.c @@ -126,6 +129,7 @@ common/tr_filter.c \ common/tr_constraint.c \ common/tr_debug.c \ common/tr_name.c \ +common/tr_gss.c \ common/tr_apc.c \ common/tr_comm.c \ tid/tid_req.c \ diff --git a/common/tr_config.c b/common/tr_config.c index 0cebfbf..b733787 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -41,11 +41,13 @@ #include #include #include +#include #include #include #include #include #include +#include void tr_print_config (TR_CFG *cfg) { tr_notice("tr_print_config: Logging running trust router configuration."); @@ -871,41 +873,58 @@ cleanup: return realms; } -static TR_CFG_RC tr_cfg_parse_gss_names(TR_RP_CLIENT *client, json_t *jgss_names) +static TR_GSS_NAMES *tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_CFG_RC *rc) { + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + TR_GSS_NAMES *gn=NULL; json_t *jname=NULL; int ii=0; TR_NAME *name=NULL; - if ((client==NULL) || (jgss_names==NULL)) { + if ((rc==NULL) || (jgss_names==NULL)) { tr_err("tr_cfg_parse_gss_names: Bad parameters."); - return TR_CFG_BAD_PARAMS; + *rc=TR_CFG_BAD_PARAMS; + } if (!json_is_array(jgss_names)) { tr_err("tr_cfg_parse_gss_names: gss_names not an array."); - return TR_CFG_NOPARSE; + *rc=TR_CFG_NOPARSE; + goto cleanup; } + gn=tr_gss_names_new(tmp_ctx); for (ii=0; iigss_names=tr_cfg_parse_gss_names(client, json_object_get(jrealm, "gss_names"), &call_rc); + if (call_rc!=TR_CFG_SUCCESS) { tr_err("tr_cfg_parse_one_rp_client: could not parse gss_names."); *rc=TR_CFG_NOPARSE; @@ -1128,9 +1148,6 @@ cleanup: if (new_idp_realms!=NULL) { trc->idp_realms=tr_idp_realm_add(trc->idp_realms, new_idp_realms); /* fixes talloc contexts except for head*/ talloc_steal(trc, trc->idp_realms); /* make sure the head is in the right context */ -#if 0 - trc->comms=tr_cfg_comm_idp_update(trc, trc->comms, new_idp_realms, &rc); /* put realm info in community table */ -#endif } if (new_rp_clients!=NULL) { @@ -1167,6 +1184,94 @@ static TR_CFG_RC tr_cfg_parse_local_orgs(TR_CFG *trc, json_t *jcfg) return TR_CFG_SUCCESS; } + +static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + json_t *jhost=NULL; + json_t *jport=NULL; + json_t *jgss=NULL; + TRP_PEER *new_peer=NULL; + TR_GSS_NAMES *names=NULL; + TR_CFG_RC rc=TR_CFG_ERROR; + + jhost=json_object_get(jporg, "hostname"); + jport=json_object_get(jporg, "port"); + jgss=json_object_get(jporg, "gss_names"); + + if ((jhost==NULL) || (!json_is_string(jhost))) { + tr_err("tr_cfg_parse_one_peer_org: hostname not specified or not a string."); + rc=TR_CFG_NOPARSE; + goto cleanup; + } + + if ((jport!=NULL) && (!json_is_number(jport))) { + /* note that not specifying the port is allowed, but if set it must be a number */ + tr_err("tr_cfg_parse_one_peer_org: port is not a number."); + rc=TR_CFG_NOPARSE; + goto cleanup; + } + + if ((jgss==NULL) || (!json_is_array(jgss))) { + tr_err("tr_cfg_parse_one_peer_org: gss_names not specified or not an array."); + rc=TR_CFG_NOPARSE; + goto cleanup; + } + + new_peer=trp_peer_new(tmp_ctx); + if (new_peer==NULL) { + tr_err("tr_cfg_parse_one_peer_org: could not allocate new peer."); + rc=TR_CFG_NOMEM; + goto cleanup; + } + + trp_peer_set_server(new_peer, json_string_value(jhost)); + if (jport==NULL) + trp_peer_set_port(new_peer, TRP_PORT); + else + trp_peer_set_port(new_peer, json_integer_value(jport)); + + names=tr_cfg_parse_gss_names(tmp_ctx, jgss, &rc); + if (rc!=TR_CFG_SUCCESS) { + tr_err("tr_cfg_parse_one_peer_org: unable to parse gss names."); + rc=TR_CFG_NOPARSE; + goto cleanup; + } + trp_peer_set_gss_names(new_peer, names); + + /* success! */ + trp_ptable_add(trc->peers, new_peer); + rc=TR_CFG_SUCCESS; + + cleanup: + talloc_free(tmp_ctx); + return rc; +} + +/* Parse peer organizations, if present. Returns success if there are none. */ +static TR_CFG_RC tr_cfg_parse_peer_orgs(TR_CFG *trc, json_t *jcfg) +{ + json_t *jpeerorgs=NULL; + int ii=0; + + jpeerorgs=json_object_get(jcfg, "peer_organizations"); + if (jpeerorgs==NULL) + return TR_CFG_SUCCESS; + + if (!json_is_array(jpeerorgs)) { + tr_err("tr_cfg_parse_peer_orgs: peer_organizations is not an array."); + return TR_CFG_NOPARSE; + } + + for (ii=0; iinew->peers=trp_ptable_new(cfg_mgr); + /* Parse configuration information from each config file */ for (ii=0; iid_name); /* must free result with talloc_free */ @@ -1558,7 +1656,6 @@ TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *tr_cfg, TR_NAME *idp_id, TR_CFG_RC *rc) TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc) { TR_RP_CLIENT *cfg_rp; - int i; if ((!tr_cfg) || (!rp_gss)) { if (rc) @@ -1567,11 +1664,9 @@ TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc) } for (cfg_rp = tr_cfg->rp_clients; NULL != cfg_rp; cfg_rp = cfg_rp->next) { - for (i = 0; i < TR_MAX_GSS_NAMES; i++) { - if (!tr_name_cmp (rp_gss, cfg_rp->gss_names[i])) { - tr_debug("tr_cfg_find_rp: Found %s.", rp_gss->buf); - return cfg_rp; - } + if (tr_gss_names_matches(cfg_rp->gss_names, rp_gss)) { + tr_debug("tr_cfg_find_rp: Found %s.", rp_gss->buf); + return cfg_rp; } } /* if we didn't find one, return NULL */ diff --git a/common/tr_filter.c b/common/tr_filter.c index cc59dd0..65ee1f9 100644 --- a/common/tr_filter.c +++ b/common/tr_filter.c @@ -126,13 +126,14 @@ int tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match) return -1; /* no space left */ } -/* returns 1 if the spec exactly matches */ +/* returns 1 if the spec matches */ int tr_fspec_matches(TR_FSPEC *fspec, TR_NAME *name) { int ii=0; for (ii=0; iibuf, fspec->match[ii]->buf)) + if ((fspec->match[ii]!=NULL) && + (0!=tr_prefix_wildcard_match(name->buf, fspec->match[ii]->buf))) return 1; } return 0; diff --git a/common/tr_rp.c b/common/tr_rp.c index 4196d3d..96c7254 100644 --- a/common/tr_rp.c +++ b/common/tr_rp.c @@ -36,32 +36,24 @@ #include #include +#include #include #include #include static int tr_rp_client_destructor(void *obj) { - TR_RP_CLIENT *client=talloc_get_type_abort(obj, TR_RP_CLIENT); - int ii=0; - - for (ii=0; iigss_names[ii]!=NULL) - tr_free_name(client->gss_names[ii]); - } return 0; } TR_RP_CLIENT *tr_rp_client_new(TALLOC_CTX *mem_ctx) { TR_RP_CLIENT *client=talloc(mem_ctx, TR_RP_CLIENT); - int ii=0; if (client!=NULL) { client->next=NULL; client->comm_next=NULL; - for (ii=0; iigss_names[ii]=NULL; + client->gss_names=NULL; client->filter=NULL; talloc_set_destructor((void *)client, tr_rp_client_destructor); } @@ -100,14 +92,7 @@ TR_RP_CLIENT *tr_rp_client_add(TR_RP_CLIENT *clients, TR_RP_CLIENT *new) int tr_rp_client_add_gss_name(TR_RP_CLIENT *rp_client, TR_NAME *gss_name) { - int ii=0; - for (ii=0; iigss_names[ii]) { - rp_client->gss_names[ii]=gss_name; - return 0; /* success */ - } - } - return -1; /* error */ + return tr_gss_names_add(rp_client->gss_names, gss_name); } int tr_rp_client_set_filter(TR_RP_CLIENT *client, TR_FILTER *filt) @@ -122,7 +107,6 @@ int tr_rp_client_set_filter(TR_RP_CLIENT *client, TR_FILTER *filt) TR_RP_CLIENT *tr_rp_client_lookup(TR_RP_CLIENT *rp_clients, TR_NAME *gss_name) { TR_RP_CLIENT *rp = NULL; - int i = 0; if ((!rp_clients) || (!gss_name)) { tr_debug("tr_rp_client_lookup: Bad parameters."); @@ -130,14 +114,11 @@ TR_RP_CLIENT *tr_rp_client_lookup(TR_RP_CLIENT *rp_clients, TR_NAME *gss_name) } for (rp = rp_clients; NULL != rp; rp = rp->next) { - for (i = 0; ((i < TR_MAX_GSS_NAMES) && (NULL != (rp->gss_names[i]))); i++) { - if (!tr_name_cmp(gss_name, rp->gss_names[i])) { - return rp; - } - } + if (tr_gss_names_matches(rp->gss_names, gss_name)) + return rp; } return NULL; - } +} /* talloc note: lists of idp realms should be assembled using * tr_idp_realm_add(). This will put all of the elements in the diff --git a/include/tr_config.h b/include/tr_config.h index 20f0365..8bd9e5b 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #define TR_DEFAULT_MAX_TREE_DEPTH 12 @@ -84,6 +85,7 @@ typedef struct tr_cfg { TR_CFG_INTERNAL *internal; /* internal trust router config */ TR_IDP_REALM *idp_realms; /* locally associated IDP Realms */ TR_RP_CLIENT *rp_clients; /* locally associated RP Clients */ + TRP_PTABLE *peers; /* TRP peer table */ TR_COMM *comms; /* locally-known communities */ TR_AAA_SERVER *default_servers; /* default server list */ /* TBD -- Global Filters */ diff --git a/include/tr_rp.h b/include/tr_rp.h index c991ff7..9db8c15 100644 --- a/include/tr_rp.h +++ b/include/tr_rp.h @@ -37,14 +37,13 @@ #include +#include #include -#define TR_MAX_GSS_NAMES 5 - typedef struct tr_rp_client { struct tr_rp_client *next; struct tr_rp_client *comm_next; - TR_NAME *gss_names[TR_MAX_GSS_NAMES]; + TR_GSS_NAMES *gss_names; TR_FILTER *filter; } TR_RP_CLIENT; diff --git a/include/trp_internal.h b/include/trp_internal.h index ca870c1..c6828f6 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -163,6 +163,7 @@ TRP_RC trpc_send_msg(TRPC_INSTANCE *trpc, const char *msg_content); TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx); void trps_free (TRPS_INSTANCE *trps); +void trps_set_ptable(TRPS_INSTANCE *trps, TRP_PTABLE *ptable); TRP_RC trps_init_rtable(TRPS_INSTANCE *trps); void trps_clear_rtable(TRPS_INSTANCE *trps); void trps_set_connect_interval(TRPS_INSTANCE *trps, unsigned int interval); diff --git a/include/trp_ptable.h b/include/trp_ptable.h index 6881ee8..ca022ad 100644 --- a/include/trp_ptable.h +++ b/include/trp_ptable.h @@ -5,7 +5,8 @@ #include #include -#include +#include +#include typedef enum trp_peer_conn_status { PEER_DISCONNECTED=0, @@ -16,7 +17,7 @@ typedef struct trp_peer TRP_PEER; struct trp_peer { TRP_PEER *next; /* for making a linked list */ char *server; - TR_NAME *gssname; + TR_GSS_NAMES *gss_names; TR_NAME *servicename; unsigned int port; unsigned int linkcost; @@ -38,7 +39,7 @@ TRP_PTABLE *trp_ptable_new(TALLOC_CTX *memctx); void trp_ptable_free(TRP_PTABLE *ptbl); TRP_RC trp_ptable_add(TRP_PTABLE *ptbl, TRP_PEER *newpeer); TRP_RC trp_ptable_remove(TRP_PTABLE *ptbl, TRP_PEER *peer); -TRP_PEER *trp_ptable_find_gssname(TRP_PTABLE *ptbl, TR_NAME *gssname); +TRP_PEER *trp_ptable_find_gss_name(TRP_PTABLE *ptbl, TR_NAME *gssname); TRP_PEER *trp_ptable_find_servicename(TRP_PTABLE *ptbl, TR_NAME *servicename); char *trp_ptable_to_str(TALLOC_CTX *memctx, TRP_PTABLE *ptbl, const char *sep, const char *lineterm); @@ -49,11 +50,13 @@ void trp_ptable_iter_free(TRP_PTABLE_ITER *iter); TRP_PEER *trp_peer_new(TALLOC_CTX *memctx); void trp_peer_free(TRP_PEER *peer); +TR_NAME *trp_peer_get_label(TRP_PEER *peer); +TR_NAME *trp_peer_dup_label(TRP_PEER *peer); char *trp_peer_get_server(TRP_PEER *peer); -void trp_peer_set_server(TRP_PEER *peer, char *server); -void trp_peer_set_gssname(TRP_PEER *peer, TR_NAME *gssname); -TR_NAME *trp_peer_get_gssname(TRP_PEER *peer); -TR_NAME *trp_peer_dup_gssname(TRP_PEER *peer); +void trp_peer_set_server(TRP_PEER *peer, const char *server); +void trp_peer_add_gss_name(TRP_PEER *peer, TR_NAME *gssname); +void trp_peer_set_gss_names(TRP_PEER *peer, TR_GSS_NAMES *gss_names); +TR_GSS_NAMES *trp_peer_get_gss_names(TRP_PEER *peer); TR_NAME *trp_peer_get_servicename(TRP_PEER *peer); TR_NAME *trp_peer_dup_servicename(TRP_PEER *peer); unsigned int trp_peer_get_port(TRP_PEER *peer); diff --git a/tr/tr_main.c b/tr/tr_main.c index 15c17a1..e18945c 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -292,7 +292,7 @@ int main(int argc, char *argv[]) return 1; } trp_peer_set_server(hc_peer, "epsilon.vmnet"); - trp_peer_set_gssname(hc_peer, tr_new_name("tr-epsilon-vmnet@apc.painless-security.com")); + trp_peer_add_gss_name(hc_peer, tr_new_name("tr-epsilon-vmnet@apc.painless-security.com")); trp_peer_set_conn_status_cb(hc_peer, tr_peer_status_change, (void *)(tr->trps)); switch (tr->trps->port) { case 10000: @@ -316,7 +316,7 @@ int main(int argc, char *argv[]) return 1; } trp_peer_set_server(hc_peer, "epsilon-trpc.vmnet"); - trp_peer_set_gssname(hc_peer, tr_new_name("trpc@apc.painless-security.com")); + trp_peer_add_gss_name(hc_peer, tr_new_name("trpc@apc.painless-security.com")); trp_peer_set_port(hc_peer, 10002); /* not really used */ if (TRP_SUCCESS != trps_add_peer(tr->trps, hc_peer)) { tr_crit("Unable to add peer."); diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 0d87439..ab391a5 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -757,8 +757,9 @@ TRP_RC tr_connect_to_peers(TRPS_INSTANCE *trps, struct event *ev) peer=trp_ptable_iter_next(iter)) { if (trps_find_trpc(trps, peer)==NULL) { + TR_NAME *label=trp_peer_get_label(peer); tr_debug("tr_connect_to_peers: %.*s missing connection.", - trp_peer_get_gssname(peer)->len, trp_peer_get_gssname(peer)->buf); + label->len, label->buf); /* has it been long enough since we last tried? */ if (tr_conn_attempt_due(trps, peer, &curtime)) { trp_peer_set_last_conn_attempt(peer, &curtime); /* we are trying again now */ @@ -795,6 +796,7 @@ void tr_config_changed(TR_CFG *new_cfg, void *cookie) trps_set_connect_interval(trps, new_cfg->internal->trp_connect_interval); trps_set_update_interval(trps, new_cfg->internal->trp_update_interval); trps_set_sweep_interval(trps, new_cfg->internal->trp_sweep_interval); + trps_set_ptable(trps, new_cfg->peers); trps_clear_rtable(trps); /* should we do this every time??? */ tr_add_local_routes(trps, new_cfg); /* should we do this every time??? */ trps_update_active_routes(trps); /* find new routes */ diff --git a/trp/trp_ptable.c b/trp/trp_ptable.c index 14a2509..53963e8 100644 --- a/trp/trp_ptable.c +++ b/trp/trp_ptable.c @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -11,8 +12,6 @@ static int trp_peer_destructor(void *object) TRP_PEER *peer=talloc_get_type_abort(object, TRP_PEER); if (peer->servicename!=NULL) tr_free_name(peer->servicename); - if (peer->gssname!=NULL) - tr_free_name(peer->gssname); return 0; } TRP_PEER *trp_peer_new(TALLOC_CTX *memctx) @@ -22,7 +21,7 @@ TRP_PEER *trp_peer_new(TALLOC_CTX *memctx) peer->next=NULL; peer->server=NULL; peer->servicename=NULL; - peer->gssname=NULL; + peer->gss_names=NULL; peer->port=0; peer->linkcost=TRP_LINKCOST_DEFAULT; peer->last_conn_attempt=(struct timespec){0,0}; @@ -48,6 +47,29 @@ static TRP_PEER *trp_peer_tail(TRP_PEER *peer) return peer; } + +/* Get a name that identifies this peer for display to the user, etc. + * Do not modify or free the label. */ +TR_NAME *trp_peer_get_label(TRP_PEER *peer) +{ + TR_GSS_NAMES_ITER *iter=tr_gss_names_iter_new(NULL); + TR_NAME *name=NULL; + + /* for now, use the first gss name */ + if (iter!=NULL) { + name=tr_gss_names_iter_first(iter, peer->gss_names); + talloc_free(iter); + } + return name; +} + +/* Get a name that identifies this peer for display to the user, etc. + * Makes a copy, caller is responsible for freeing. */ +TR_NAME *trp_peer_dup_label(TRP_PEER *peer) +{ + return tr_dup_name(trp_peer_get_label(peer));; +} + char *trp_peer_get_server(TRP_PEER *peer) { return peer->server; @@ -70,28 +92,33 @@ static void trp_peer_set_servicename(TRP_PEER *peer, const char *server) } } -/* copies input; on error, peer->gssname will be null */ -void trp_peer_set_server(TRP_PEER *peer, char *server) +/* copies input; on error, peer->servicename will be null */ +void trp_peer_set_server(TRP_PEER *peer, const char *server) { peer->server=talloc_strdup(peer, server); /* will be null on error */ trp_peer_set_servicename(peer, server); } -void trp_peer_set_gssname(TRP_PEER *peer, TR_NAME *gssname) +void trp_peer_add_gss_name(TRP_PEER *peer, TR_NAME *gss_name) { - peer->gssname=gssname; + if (peer->gss_names==NULL) + trp_peer_set_gss_names(peer, tr_gss_names_new(peer)); + tr_gss_names_add(peer->gss_names, gss_name); } -/* get the peer gssname, caller must not free the result */ -TR_NAME *trp_peer_get_gssname(TRP_PEER *peer) +void trp_peer_set_gss_names(TRP_PEER *peer, TR_GSS_NAMES *gss_names) { - return peer->gssname; + if (peer->gss_names!=NULL) + talloc_free(peer->gss_names); + + peer->gss_names=gss_names; + talloc_steal(peer, gss_names); } -/* get a copy of the peer gssname, caller must free via tr_free_name() */ -TR_NAME *trp_peer_dup_gssname(TRP_PEER *peer) +/* get the peer gss_names, caller must not free the result */ +TR_GSS_NAMES *trp_peer_get_gss_names(TRP_PEER *peer) { - return tr_dup_name(peer->gssname); + return peer->gss_names; } /* get the service name (i.e., gssname we see when we connect to this peer) */ @@ -162,10 +189,11 @@ TRP_PTABLE *trp_ptable_new(TALLOC_CTX *memctx) void trp_peer_set_outgoing_status(TRP_PEER *peer, TRP_PEER_CONN_STATUS status) { + TR_NAME *peer_label=trp_peer_get_label(peer); int was_connected=trp_peer_is_connected(peer); peer->outgoing_status=status; tr_debug("trp_peer_set_outgoing_status: %s: status=%d peer connected was %d now %d.", - trp_peer_get_gssname(peer)->buf, status, was_connected, trp_peer_is_connected(peer)); + peer_label->buf, status, was_connected, trp_peer_is_connected(peer)); if ((trp_peer_is_connected(peer) != was_connected) && (peer->conn_status_cb!=NULL)) peer->conn_status_cb(peer, peer->conn_status_cookie); } @@ -177,10 +205,11 @@ TRP_PEER_CONN_STATUS trp_peer_get_outgoing_status(TRP_PEER *peer) void trp_peer_set_incoming_status(TRP_PEER *peer, TRP_PEER_CONN_STATUS status) { + TR_NAME *peer_label=trp_peer_get_label(peer); int was_connected=trp_peer_is_connected(peer); peer->incoming_status=status; tr_debug("trp_peer_set_incoming_status: %s: status=%d peer connected was %d now %d.", - trp_peer_get_gssname(peer)->buf, status, was_connected, trp_peer_is_connected(peer)); + peer_label->buf, status, was_connected, trp_peer_is_connected(peer)); if ((trp_peer_is_connected(peer) != was_connected) && (peer->conn_status_cb!=NULL)) peer->conn_status_cb(peer, peer->conn_status_cookie); } @@ -202,12 +231,12 @@ void trp_ptable_free(TRP_PTABLE *ptbl) TRP_RC trp_ptable_add(TRP_PTABLE *ptbl, TRP_PEER *newpeer) { - if (ptbl->head==NULL) { + if (ptbl->head==NULL) ptbl->head=newpeer; - } else { + else trp_peer_tail(ptbl->head)->next=newpeer; - talloc_steal(ptbl, newpeer); - } + + talloc_steal(ptbl, newpeer); return TRP_SUCCESS; } @@ -236,10 +265,10 @@ TRP_RC trp_ptable_remove(TRP_PTABLE *ptbl, TRP_PEER *peer) return TRP_ERROR; } -TRP_PEER *trp_ptable_find_gssname(TRP_PTABLE *ptbl, TR_NAME *gssname) +TRP_PEER *trp_ptable_find_gss_name(TRP_PTABLE *ptbl, TR_NAME *gssname) { TRP_PEER *cur=ptbl->head; - while ((cur!=NULL) && (0 != tr_name_cmp(trp_peer_get_gssname(cur), gssname))) + while ((cur!=NULL) && (!tr_gss_names_matches(trp_peer_get_gss_names(cur), gssname))) cur=cur->next; return cur; } @@ -291,13 +320,17 @@ TRP_PTABLE_ITER *trp_ptable_iter_new(TALLOC_CTX *mem_ctx) TRP_PEER *trp_ptable_iter_first(TRP_PTABLE_ITER *iter, TRP_PTABLE *ptbl) { - *iter=ptbl->head; + if (ptbl==NULL) + *iter=NULL; + else + *iter=ptbl->head; return *iter; } TRP_PEER *trp_ptable_iter_next(TRP_PTABLE_ITER *iter) { - *iter=(*iter)->next; + if (*iter!=NULL) + *iter=(*iter)->next; return *iter; } diff --git a/trp/trps.c b/trp/trps.c index 1997c54..7c8f6ac 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx) trps->trpc=NULL; trps->update_interval=(struct timeval){0,0}; trps->sweep_interval=(struct timeval){0,0}; + trps->ptable=NULL; trps->mq=tr_mq_new(trps); if (trps->mq==NULL) { @@ -40,13 +42,6 @@ TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx) return NULL; } - trps->ptable=trp_ptable_new(trps); - if (trps->ptable==NULL) { - /* failed to allocate ptable */ - talloc_free(trps); - return NULL; - } - trps->rtable=NULL; if (trps_init_rtable(trps) != TRP_SUCCESS) { /* failed to allocate rtable */ @@ -128,15 +123,22 @@ void trps_set_sweep_interval(TRPS_INSTANCE *trps, unsigned int interval) trps->sweep_interval.tv_usec=0; } +void trps_set_ptable(TRPS_INSTANCE *trps, TRP_PTABLE *ptable) +{ + if (trps->ptable!=NULL) + trp_ptable_free(trps->ptable); + trps->ptable=ptable; +} + TRPC_INSTANCE *trps_find_trpc(TRPS_INSTANCE *trps, TRP_PEER *peer) { TRPC_INSTANCE *cur=NULL; TR_NAME *name=NULL; - TR_NAME *peer_gssname=trp_peer_get_gssname(peer); + TR_GSS_NAMES *peer_gssnames=trp_peer_get_gss_names(peer); for (cur=trps->trpc; cur!=NULL; cur=trpc_get_next(cur)) { name=trpc_get_gssname(cur); - if ((name!=NULL) && (0==tr_name_cmp(peer_gssname, name))) { + if ((name!=NULL) && (tr_gss_names_matches(peer_gssnames, name))) { break; } } @@ -898,7 +900,7 @@ static TRP_INFOREC *trps_route_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *tr /* all routes to a single peer, unless comm/realm are specified (both or neither must be NULL) */ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps, - TR_NAME *peer_gssname, + TRP_PEER *peer, TRP_UPDATE_TYPE update_type, TR_NAME *comm, TR_NAME *realm) @@ -911,20 +913,20 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps, size_t n_updates=0, ii=0; char *encoded=NULL; TRP_RC rc=TRP_ERROR; - TRP_PEER *peer=trps_get_peer_by_gssname(trps, peer_gssname); + TR_NAME *peer_label=trp_peer_get_label(peer); switch (update_type) { case TRP_UPDATE_TRIGGERED: tr_debug("trps_update_one_peer: preparing triggered route update for %.*s", - peer_gssname->len, peer_gssname->buf); + peer_label->len, peer_label->buf); break; case TRP_UPDATE_SCHEDULED: tr_debug("trps_update_one_peer: preparing scheduled route update for %.*s", - peer_gssname->len, peer_gssname->buf); + peer_label->len, peer_label->buf); break; case TRP_UPDATE_REQUESTED: tr_debug("trps_update_one_peer: preparing requested route update for %.*s", - peer_gssname->len, peer_gssname->buf); + peer_label->len, peer_label->buf); } /* do not fill in peer, recipient does that */ @@ -932,7 +934,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps, /* do all realms */ update_list=trps_select_updates_for_peer(tmp_ctx, trps, - peer_gssname, + peer_label, update_type==TRP_UPDATE_TRIGGERED, &n_updates); } else if ((comm!=NULL) && (realm!=NULL)) { @@ -943,7 +945,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps, rc=TRP_NOMEM; goto cleanup; } - *update_list=trps_select_realm_update(trps, comm, realm, peer_gssname); + *update_list=trps_select_realm_update(trps, comm, realm, peer_label); if (*update_list==NULL) { /* we have no actual update to send back, MUST send a retraction */ tr_debug("trps_update_one_peer: community/realm without route requested, sending mandatory retraction."); @@ -1011,6 +1013,9 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE update_type) TRP_PEER *peer=NULL; TRP_RC rc=TRP_SUCCESS; + if (trps->ptable==NULL) + return TRP_SUCCESS; /* no peers, nothing to do */ + if (iter==NULL) { tr_err("trps_update: failed to allocate peer table iterator."); talloc_free(tmp_ctx); @@ -1022,12 +1027,12 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE update_type) peer=trp_ptable_iter_next(iter)) { if (!trps_peer_connected(trps, peer)) { - TR_NAME *peer_gssname=trp_peer_get_gssname(peer); + TR_NAME *peer_label=trp_peer_get_label(peer); tr_debug("trps_update: no TRP connection to %.*s, skipping.", - peer_gssname->len, peer_gssname->buf); + peer_label->len, peer_label->buf); continue; } - rc=trps_update_one_peer(trps, trp_peer_get_gssname(peer), update_type, NULL, NULL); + rc=trps_update_one_peer(trps, peer, update_type, NULL, NULL); } trp_ptable_iter_free(iter); @@ -1045,16 +1050,27 @@ TRP_RC trps_add_route(TRPS_INSTANCE *trps, TRP_ROUTE *route) /* steals the peer object */ TRP_RC trps_add_peer(TRPS_INSTANCE *trps, TRP_PEER *peer) { + if (trps->ptable==NULL) { + trps->ptable=trp_ptable_new(trps); + if (trps->ptable==NULL) + return TRP_NOMEM; + } return trp_ptable_add(trps->ptable, peer); } TRP_PEER *trps_get_peer_by_gssname(TRPS_INSTANCE *trps, TR_NAME *gssname) { - return trp_ptable_find_gssname(trps->ptable, gssname); + if (trps->ptable==NULL) + return NULL; + + return trp_ptable_find_gss_name(trps->ptable, gssname); } TRP_PEER *trps_get_peer_by_servicename(TRPS_INSTANCE *trps, TR_NAME *servicename) { + if (trps->ptable==NULL) + return NULL; + return trp_ptable_find_servicename(trps->ptable, servicename); } @@ -1092,7 +1108,11 @@ static TRP_RC trps_handle_request(TRPS_INSTANCE *trps, TRP_REQ *req) tr_debug("trps_handle_request: all routes requested."); /* leave comm/realm NULL */ } - return trps_update_one_peer(trps, trp_req_get_peer(req), TRP_UPDATE_REQUESTED, comm, realm); + return trps_update_one_peer(trps, + trps_get_peer_by_gssname(trps, trp_req_get_peer(req)), + TRP_UPDATE_REQUESTED, + comm, + realm); } -- 2.1.4