{
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
TR_APC *cur=NULL;
- TR_APC *new=tr_apc_dup(tmp_ctx, apc);
+ TR_APC *new=NULL;
- if (new==NULL)
+ if (apc==NULL)
+ return NULL;
+
+ if (NULL==(new=tr_apc_dup_one(tmp_ctx, apc)))
return NULL;
for (cur=new,apc=apc->next; apc!=NULL; cur=cur->next,apc=apc->next) {
static void tr_realm_set_rp(TR_REALM *realm, TR_RP_REALM *rp)
{
- if (realm->rp!=NULL)
- talloc_free(realm->rp);
- if (realm->idp!=NULL) {
- talloc_free(realm->idp);
+ if (realm->idp!=NULL)
realm->idp=NULL;
- }
realm->role=TR_ROLE_RP;
realm->rp=rp;
}
static void tr_realm_set_idp(TR_REALM *realm, TR_IDP_REALM *idp)
{
- if (realm->idp!=NULL)
- talloc_free(realm->idp);
- if (realm->rp!=NULL) {
- talloc_free(realm->rp);
+ if (realm->rp!=NULL)
realm->rp=NULL;
- }
realm->role=TR_ROLE_IDP;
realm->idp=idp;
}
TR_COMM_MEMB *memb=talloc(mem_ctx, TR_COMM_MEMB);
if (memb!=NULL) {
memb->next=NULL;
+ memb->origin_next=NULL;
memb->idp=NULL;
memb->rp=NULL;
memb->comm=NULL;
trc,
json_array_get(jcomms, i),
&rc))) {
- return rc;
+ return rc;
}
tr_debug("tr_cfg_parse_comms: Community configured: %s.",
tr_comm_get_id(comm)->buf);
/* Read attribute attr from msg as a string. Copies string into mem_ctx context so jmsg can
* be destroyed safely. Returns nonzero on error. */
-static int tr_msg_get_json_string(json_t *jmsg, const char *attr, char **dest, TALLOC_CTX *mem_ctx)
+static TRP_RC tr_msg_get_json_string(json_t *jmsg, const char *attr, char **dest, TALLOC_CTX *mem_ctx)
{
json_t *obj;
obj=json_object_get(jmsg, attr);
if (obj == NULL)
- return -1;
+ return TRP_ERROR;
/* check type */
if (!json_is_string(obj))
- return -1;
+ return TRP_ERROR;
*dest=talloc_strdup(mem_ctx, json_string_value(obj));
if (*dest==NULL)
- return -1;
+ return TRP_ERROR;
- return 0;
+ return TRP_SUCCESS;
}
enum msg_type tr_msg_get_msg_type(TR_MSG *msg)
*rc=TRP_SUCCESS;
if (apc_list!=NULL)
- talloc_steal(apc_list, mem_ctx);
+ talloc_steal(mem_ctx, apc_list);
cleanup:
talloc_free(tmp_ctx);
TRP_RC rc=TRP_ERROR;
char *s=NULL;
- if (0!=tr_msg_get_json_string(jrecord, "record_type", &s, tmp_ctx))
+ if (TRP_SUCCESS!=tr_msg_get_json_string(jrecord, "record_type", &s, tmp_ctx))
goto cleanup;
rectype=trp_inforec_type_from_string(s);
}
encoded=json_dumps(jmsg, 0);
+ tr_debug("tr_msg_encode: outgoing msg=%s", encoded);
json_decref(jmsg);
return encoded;
}
new_rec->owner_realm=NULL;
new_rec->owner_contact=NULL;
new_rec->provenance=NULL;
+ new_rec->interval=0;
talloc_set_destructor((void *)new_rec, trp_inforec_comm_destructor);
new_data->comm=new_rec;
}
TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec)
{
- if (rec)
+ if (rec!=NULL)
return rec->type;
else
return TRP_INFOREC_TYPE_UNKNOWN;
{
switch (rec->type) {
case TRP_INFOREC_TYPE_ROUTE:
- if (rec->data->route!=NULL) {
- rec->data->route->next_hop=next_hop;
- return TRP_SUCCESS;
- }
+ if (rec->data->route==NULL)
+ return TRP_ERROR;
+ rec->data->route->next_hop=next_hop;
+ break;
+ case TRP_INFOREC_TYPE_COMMUNITY:
+ /* next hop not used for community records */
break;
default:
break;
}
- return TRP_ERROR;
+ return TRP_SUCCESS;
}
unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
rec->data->comm->apcs=apcs;
talloc_steal(rec, apcs);
return TRP_SUCCESS;
- default:
- break;
}
break;
+
+ default:
+ break;
}
return TRP_ERROR;
}
return TRP_ERROR;
}
+static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *peer)
+{
+ json_t *jpeer=NULL;
+
+ switch (rec->type) {
+ case TRP_INFOREC_TYPE_ROUTE:
+ /* no provenance list */
+ break;
+ case TRP_INFOREC_TYPE_COMMUNITY:
+ jpeer=tr_name_to_json_string(peer);
+ if (jpeer==NULL)
+ return TRP_ERROR;
+ if (rec->data->comm->provenance==NULL) {
+ rec->data->comm->provenance=json_array();
+ if (rec->data->comm->provenance==NULL) {
+ json_decref(jpeer);
+ return TRP_ERROR;
+ }
+ }
+ if (0!=json_array_append_new(rec->data->comm->provenance, jpeer)) {
+ json_decref(jpeer);
+ return TRP_ERROR;
+ }
+ break;
+ default:
+ break;
+ }
+ return TRP_SUCCESS;
+}
+
/* generic record type */
TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type)
{
void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer)
{
+ TRP_INFOREC *rec=NULL;
+ TR_NAME *cpy=NULL;
+
upd->peer=peer;
+
+ /* add to provenance list of any records that need it */
+ for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
+ if (trp_inforec_add_to_provenance(rec, cpy=tr_dup_name(peer)) != TRP_SUCCESS) {
+ tr_err("trp_upd_set_peer: error adding peer to provenance list.");
+ tr_free_name(cpy);
+ }
+ }
}
void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
if (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname)) != TRP_SUCCESS) {
- tr_err("trp_upd_set_peer: error setting peer.");
+ tr_err("trp_upd_set_next_hop: error setting next hop.");
tr_free_name(cpy);
}
}
}
break;
+ case TRP_INFOREC_TYPE_COMMUNITY:
+ /* TODO: handle community updates -jlr*/
+
default:
tr_notice("trps_validate_inforec: unsupported record type.");
return TRP_UNSUPPORTED;
goto cleanup;
}
- if ((TRP_SUCCESS!=trp_inforec_set_apcs(rec,
- tr_apc_dup(rec, tr_comm_get_apcs(comm)))) ||
- (NULL==trp_inforec_get_apcs(rec))) {
+ if ((NULL!=tr_comm_get_apcs(comm)) &&
+ ( (TRP_SUCCESS!=trp_inforec_set_apcs(rec,
+ tr_apc_dup(rec, tr_comm_get_apcs(comm)))) ||
+ (NULL==trp_inforec_get_apcs(rec)))) {
rec=NULL;
goto cleanup;
}
iter=tr_comm_iter_new(tmp_ctx);
if (iter==NULL) {
- tr_err("tr_comm_update: unable to allocate iterator.");
+ tr_err("trps_comm_update: unable to allocate iterator.");
upd=NULL;
goto cleanup;
}
memb=tr_comm_memb_iter_next(iter)) {
rec=trps_memb_to_inforec(tmp_ctx, trps, memb);
if (rec==NULL) {
- tr_err("tr_comm_update: unable to allocate inforec.");
+ tr_err("trps_comm_update: unable to allocate inforec.");
upd=NULL;
goto cleanup;
}
comm!=NULL;
comm=tr_comm_table_iter_next(comm_iter)) {
/* do every realm in this community */
+ tr_debug("trps_select_comm_updates_for_peer: looking through community %.*s",
+ tr_comm_get_id(comm)->len,
+ tr_comm_get_id(comm)->buf);
for (realm=tr_realm_iter_first(realm_iter, trps->ctable, tr_comm_get_id(comm));
realm!=NULL;
realm=tr_realm_iter_next(realm_iter)) {
/* get the update for this comm/realm */
- upd=trps_comm_update(tmp_ctx, trps, peer_gssname, comm, realm);
- if (upd!=NULL) {
+ tr_debug("trps_select_comm_updates_for_peer: adding realm %.*s",
+ tr_realm_get_id(realm)->len,
+ tr_realm_get_id(realm)->buf);
+ upd=trps_comm_update(mem_ctx, trps, peer_gssname, comm, realm);
+ if (upd!=NULL)
g_ptr_array_add(updates, upd);
- }
}
}
- /* move anything needed into mem_ctx */
-
-
cleanup:
talloc_free(tmp_ctx);
return rc;
}
/* First, gather route updates. */
+ tr_debug("trps_update_one_peer: selecting route updates for %.*s.", peer_label->len, peer_label->buf);
if ((comm==NULL) && (realm==NULL)) {
/* do all realms */
rc=trps_select_route_updates_for_peer(tmp_ctx,
}
/* Second, gather community updates */
+ tr_debug("trps_update_one_peer: selecting community updates for %.*s.", peer_label->len, peer_label->buf);
rc=trps_select_comm_updates_for_peer(tmp_ctx, updates, trps, peer_label);
/* see if we have anything to send */
tr_debug("trps_update_one_peer: no updates for %.*s", peer_label->len, peer_label->buf);
else {
tr_debug("trps_update_one_peer: sending %d update messages.", updates->len);
- for (ii=0; NULL!=(upd=(TRP_UPD *)g_ptr_array_index(updates, ii)); ii++) {
+ for (ii=0; ii<updates->len; ii++) {
+ upd=(TRP_UPD *)g_ptr_array_index(updates, ii);
/* now encode the update message */
tr_msg_set_trp_upd(&msg, upd);
encoded=tr_msg_encode(&msg);