+/* community membership - link realms to their communities */
+typedef struct tr_comm_memb {
+ struct tr_comm_memb *next;
+ struct tr_comm_memb *origin_next; /* for multiple copies from different origins */
+ TR_IDP_REALM *idp; /* only set one of idp and rp, other null */
+ TR_RP_REALM *rp; /* only set one of idp and rp, other null */
+ TR_COMM *comm;
+ TR_NAME *origin;
+ json_t *provenance; /* array of names of systems traversed */
+ unsigned int interval;
+ struct timespec *expiry;
+ unsigned int times_expired; /* how many times has this expired? */
+ int triggered; /* do we need to send this with triggered updates? */
+} TR_COMM_MEMB;
+
+/* table of communities/memberships */
+struct tr_comm_table {
+ TR_COMM *comms; /* all communities */
+ TR_IDP_REALM *idp_realms; /* all idp realms */
+ TR_RP_REALM *rp_realms; /* all rp realms */
+ TR_COMM_MEMB *memberships; /* head of the linked list of membership records */
+};
+
+typedef enum tr_realm_role {
+ TR_ROLE_UNKNOWN=0,
+ TR_ROLE_IDP,
+ TR_ROLE_RP
+} TR_REALM_ROLE;
+
+typedef struct tr_realm {
+ TR_REALM_ROLE role;
+ TR_RP_REALM *rp;
+ TR_IDP_REALM *idp;
+} TR_REALM;
+
+/* nb, not all iterator routines use all members */
+typedef struct tr_comm_iter {
+ TR_COMM *cur_comm;
+ TR_COMM_MEMB *cur_memb;
+ TR_COMM_MEMB *cur_orig_head; /* for iterating along orig_next list */
+ TR_NAME *match; /* realm or comm to match */
+ TR_REALM *realm; /* handle so caller does not have to manage memory, private */
+} TR_COMM_ITER;
+
+
+TR_COMM_TABLE *tr_comm_table_new(TALLOC_CTX *mem_ctx);
+void tr_comm_table_free(TR_COMM_TABLE *ctab);
+
+TR_COMM_TABLE *tr_comm_table_new(TALLOC_CTX *mem_ctx);
+void tr_comm_table_free(TR_COMM_TABLE *ctab);
+void tr_comm_table_sweep(TR_COMM_TABLE *ctab);
+int tr_comm_table_add_comm(TR_COMM_TABLE *ctab, TR_COMM *new);
+void tr_comm_table_remove_comm(TR_COMM_TABLE *ctab, TR_COMM *comm);
+TR_RP_REALM *tr_comm_table_find_rp_realm(TR_COMM_TABLE *ctab, TR_NAME *realm_id);
+void tr_comm_table_add_rp_realm(TR_COMM_TABLE *ctab, TR_RP_REALM *new);
+void tr_comm_table_remove_rp_realm(TR_COMM_TABLE *ctab, TR_RP_REALM *realm);
+TR_IDP_REALM *tr_comm_table_find_idp_realm(TR_COMM_TABLE *ctab, TR_NAME *realm_id);
+void tr_comm_table_add_idp_realm(TR_COMM_TABLE *ctab, TR_IDP_REALM *new);
+void tr_comm_table_remove_idp_realm(TR_COMM_TABLE *ctab, TR_IDP_REALM *realm);
+void tr_comm_table_add_memb(TR_COMM_TABLE *ctab, TR_COMM_MEMB *new);
+void tr_comm_table_remove_memb(TR_COMM_TABLE *ctab, TR_COMM_MEMB *memb);
+TR_COMM_MEMB *tr_comm_table_find_memb_origin(TR_COMM_TABLE *ctab, TR_NAME *realm, TR_NAME *comm, TR_NAME *origin);
+TR_COMM_MEMB *tr_comm_table_find_memb(TR_COMM_TABLE *ctab, TR_NAME *realm, TR_NAME *comm);
+TR_COMM_MEMB *tr_comm_table_find_rp_memb_origin(TR_COMM_TABLE *ctab, TR_NAME *rp_realm, TR_NAME *comm, TR_NAME *origin);
+TR_COMM_MEMB *tr_comm_table_find_rp_memb(TR_COMM_TABLE *ctab, TR_NAME *rp_realm, TR_NAME *comm);
+TR_COMM_MEMB *tr_comm_table_find_idp_memb_origin(TR_COMM_TABLE *ctab, TR_NAME *idp_realm, TR_NAME *comm, TR_NAME *origin);
+TR_COMM_MEMB *tr_comm_table_find_idp_memb(TR_COMM_TABLE *ctab, TR_NAME *idp_realm, TR_NAME *comm);
+TR_COMM *tr_comm_table_find_comm(TR_COMM_TABLE *ctab, TR_NAME *comm_id);
+size_t tr_comm_table_size(TR_COMM_TABLE *ctab);
+char *tr_comm_table_to_str(TALLOC_CTX *mem_ctx, TR_COMM_TABLE *ctab);
+void tr_comm_table_print(FILE *f, TR_COMM_TABLE *ctab);
+
+TR_COMM_MEMB *tr_comm_memb_new(TALLOC_CTX *mem_ctx);
+void tr_comm_memb_free(TR_COMM_MEMB *memb);
+int tr_comm_memb_cmp(TR_COMM_MEMB *m1, TR_COMM_MEMB *m2);
+TR_REALM_ROLE tr_comm_memb_get_role(TR_COMM_MEMB *memb);
+void tr_comm_memb_set_rp_realm(TR_COMM_MEMB *memb, TR_RP_REALM *realm);
+TR_RP_REALM *tr_comm_memb_get_rp_realm(TR_COMM_MEMB *memb);
+void tr_comm_memb_set_idp_realm(TR_COMM_MEMB *memb, TR_IDP_REALM *realm);
+TR_IDP_REALM *tr_comm_memb_get_idp_realm(TR_COMM_MEMB *memb);
+TR_NAME *tr_comm_memb_get_realm_id(TR_COMM_MEMB *memb);
+void tr_comm_memb_set_comm(TR_COMM_MEMB *memb, TR_COMM *comm);
+TR_COMM *tr_comm_memb_get_comm(TR_COMM_MEMB *memb);
+TR_NAME *tr_comm_memb_get_origin(TR_COMM_MEMB *memb);
+TR_NAME *tr_comm_memb_dup_origin(TR_COMM_MEMB *memb);
+json_t *tr_comm_memb_get_provenance(TR_COMM_MEMB *memb);
+void tr_comm_memb_set_provenance(TR_COMM_MEMB *memb, json_t *prov);
+void tr_comm_memb_add_to_provenance(TR_COMM_MEMB *memb, TR_NAME *hop);
+size_t tr_comm_memb_provenance_len(TR_COMM_MEMB *memb);
+void tr_comm_memb_set_interval(TR_COMM_MEMB *memb, unsigned int interval);
+unsigned int tr_comm_memb_get_interval(TR_COMM_MEMB *memb);
+void tr_comm_memb_set_expiry(TR_COMM_MEMB *memb, struct timespec *time);
+struct timespec *tr_comm_memb_get_expiry(TR_COMM_MEMB *memb);
+struct timespec *tr_comm_memb_get_expiry_realtime(TR_COMM_MEMB *memb, struct timespec *result);
+int tr_comm_memb_is_expired(TR_COMM_MEMB *memb, struct timespec *curtime);
+void tr_comm_memb_set_triggered(TR_COMM_MEMB *memb, int trig);
+int tr_comm_memb_is_triggered(TR_COMM_MEMB *memb);
+void tr_comm_memb_reset_times_expired(TR_COMM_MEMB *memb);
+void tr_comm_memb_expire(TR_COMM_MEMB *memb);
+unsigned int tr_comm_memb_get_times_expired(TR_COMM_MEMB *memb);
+