X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=trp%2Ftrp_upd.c;h=9c520e33ef7c3bab0defd7cba0af5358b89a8c62;hb=fd58b52dff0f0cbbd52542f1f89c2e3d50f7c58a;hp=c8bd784d6e3e439da9683d7666851f44557b6c51;hpb=c1e7f501a675cbdf1b42c7de0ba39a9478aae516;p=trust_router.git diff --git a/trp/trp_upd.c b/trp/trp_upd.c index c8bd784..9c520e3 100644 --- a/trp/trp_upd.c +++ b/trp/trp_upd.c @@ -32,11 +32,14 @@ * */ +#include #include #include -#include +#include #include +#include +#include #include @@ -78,7 +81,7 @@ TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s) struct trp_inforec_type_entry *entry=trp_inforec_type_table; while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN) - && (strcmp(s, entry->name)!=0)) { + && (strcasecmp(s, entry->name)!=0)) { entry++; } return entry->type; @@ -137,6 +140,8 @@ static int trp_inforec_comm_destructor(void *obj) tr_free_name(rec->owner_realm); if (rec->owner_contact!=NULL) tr_free_name(rec->owner_contact); + if (rec->provenance!=NULL) + json_decref(rec->provenance); return 0; } @@ -153,12 +158,14 @@ static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx) talloc_free(new_data); new_data=NULL; } else { - new_rec->type=TR_COMM_UNKNOWN; - new_rec->is_service_realm=0; - new_rec->is_idp_realm=0; + new_rec->comm_type=TR_COMM_UNKNOWN; + new_rec->role=TR_ROLE_UNKNOWN; new_rec->apcs=NULL; new_rec->owner_realm=NULL; new_rec->owner_contact=NULL; + new_rec->expiration_interval=0; + new_rec->provenance=NULL; + new_rec->interval=0; talloc_set_destructor((void *)new_rec, trp_inforec_comm_destructor); new_data->comm=new_rec; } @@ -189,7 +196,7 @@ void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_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; @@ -253,19 +260,33 @@ TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec) return tr_dup_name(trp_inforec_get_next_hop(rec)); } +/** + * Set the next hop for the inforec + * + * Returns TRP_SUCCESS if it set the next hop value for the inforec. + * Returns TRP_UNSUPPORTED if the inforec does not have a next hop record but + * otherwise nothing went wrong. + * Returns TRP_ERROR or another error if there was a failure. + * + * @param rec + * @param next_hop + * @return TRP_SUCCESS if the value was set, TRP_UNSUPPORTED if the inforec does not support next hop, or an error code on failure + */ TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop) { + /* Any inforec types that support next_hop should set it here. */ 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; + default: - break; + /* next hop not used for other records */ + return TRP_UNSUPPORTED; } - return TRP_ERROR; + return TRP_SUCCESS; } unsigned int trp_inforec_get_metric(TRP_INFOREC *rec) @@ -303,6 +324,10 @@ unsigned int trp_inforec_get_interval(TRP_INFOREC *rec) if (rec->data->route!=NULL) return rec->data->route->interval; break; + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->interval; + break; default: break; } @@ -316,14 +341,270 @@ TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval) if (rec->data->route!=NULL) { rec->data->route->interval=interval; return TRP_SUCCESS; + } + break; + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->interval=interval; + return TRP_SUCCESS; + } + default: + break; + } + return TRP_ERROR; +} + +time_t trp_inforec_get_exp_interval(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->expiration_interval; + break; + default: + break; + } + return 0; +} + +TRP_RC trp_inforec_set_exp_interval(TRP_INFOREC *rec, time_t expint) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->expiration_interval=expint; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; +} + +TR_COMM_TYPE trp_inforec_get_comm_type(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->comm_type; + break; + default: + break; + } + return TR_COMM_UNKNOWN; +} + +TRP_RC trp_inforec_set_comm_type(TRP_INFOREC *rec, TR_COMM_TYPE type) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->comm_type=type; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; +} + +TR_REALM_ROLE trp_inforec_get_role(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->role; + break; + default: + break; + } + return TR_ROLE_UNKNOWN; +} + +TRP_RC trp_inforec_set_role(TRP_INFOREC *rec, TR_REALM_ROLE role) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->role=role; + return TRP_SUCCESS; + break; + } + default: + break; + } + return TRP_ERROR; +} + +TR_APC *trp_inforec_get_apcs(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->apcs; + break; default: break; + } + return NULL; +} + +TRP_RC trp_inforec_set_apcs(TRP_INFOREC *rec, TR_APC *apcs) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->apcs=apcs; + talloc_steal(rec, apcs); + return TRP_SUCCESS; } break; + + default: + break; } return TRP_ERROR; } +TR_NAME *trp_inforec_get_owner_realm(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->owner_realm; + break; + default: + break; + } + return NULL; +} + +TRP_RC trp_inforec_set_owner_realm(TRP_INFOREC *rec, TR_NAME *name) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->owner_realm=name; + return TRP_SUCCESS; + default: + break; + } + break; + } + return TRP_ERROR; +} + +TR_NAME *trp_inforec_get_owner_contact(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->owner_contact; + break; + default: + break; + } + return NULL; +} + +TRP_RC trp_inforec_set_owner_contact(TRP_INFOREC *rec, TR_NAME *name) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + rec->data->comm->owner_contact=name; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; +} + +/* caller needs to incref the output if they're going to hang on to it */ +json_t *trp_inforec_get_provenance(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) + return rec->data->comm->provenance; + break; + default: + break; + } + return NULL; +} + +/* increments the reference count */ +TRP_RC trp_inforec_set_provenance(TRP_INFOREC *rec, json_t *prov) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_COMMUNITY: + if (rec->data->comm!=NULL) { + if (rec->data->comm->provenance!=NULL) + json_decref(rec->data->comm->provenance); + rec->data->comm->provenance=prov; + json_incref(prov); + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; +} + +static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *name) +{ + json_t *jname=NULL; + + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + /* no provenance list */ + break; + case TRP_INFOREC_TYPE_COMMUNITY: + jname=tr_name_to_json_string(name); + if (jname==NULL) + return TRP_ERROR; + if (rec->data->comm->provenance==NULL) { + rec->data->comm->provenance=json_array(); + if (rec->data->comm->provenance==NULL) { + json_decref(jname); + return TRP_ERROR; + } + } + if (0!=json_array_append_new(rec->data->comm->provenance, jname)) { + json_decref(jname); + return TRP_ERROR; + } + break; + default: + break; + } + return TRP_SUCCESS; +} + +TR_NAME *trp_inforec_dup_origin(TRP_INFOREC *rec) +{ + TR_NAME *origin=NULL; + json_t *prov=trp_inforec_get_provenance(rec); + const char *s=NULL; + + if (prov==NULL) + return NULL; + + s=json_string_value(json_array_get(prov, 0)); + if (s==NULL) { + tr_debug("trp_inforec_dup_origin: empty origin in provenance list."); + return NULL; + } + origin=tr_new_name(s); + return origin; +} + /* generic record type */ TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type) { @@ -409,6 +690,45 @@ void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec) talloc_steal(upd, rec); } +/** + * Removes and frees the selected inforec. + * + * @param upd Update to remove from + * @param rec Inforec to remove + */ +void trp_upd_remove_inforec(TRP_UPD *upd, TRP_INFOREC *rec) +{ + TRP_INFOREC *this=upd->records; + + /* special case for the first element */ + if (this==rec) { + upd->records=upd->records->next; + trp_inforec_free(this); + return; + } + + while (this->next!=NULL) { + if (this->next==rec) { + this->next=this->next->next; /* this->next is not null */ + trp_inforec_free(rec); + } + this=this->next; + } +} + +size_t trp_upd_num_inforecs(TRP_UPD *upd) +{ + size_t count=0; + TRP_INFOREC *this=upd->records; + + while (this != NULL) { + count++; + this=this->next; + } + return count; +} + + TR_NAME *trp_upd_get_realm(TRP_UPD *upd) { return upd->realm; @@ -462,20 +782,42 @@ void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port) { TRP_INFOREC *rec=NULL; TR_NAME *cpy=NULL; - + 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_free_name(cpy); + switch (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname))) { + case TRP_SUCCESS: + /* Success, the TR_NAME in cpy is now stored with the inforec */ + break; + + case TRP_UNSUPPORTED: + /* No error, but the inforec does not accept a next_hop. Free our copy. */ + tr_free_name(cpy); + break; + + default: + tr_err("trp_upd_set_next_hop: error setting next hop."); + tr_free_name(cpy); + break; } } } +void trp_upd_add_to_provenance(TRP_UPD *upd, TR_NAME *name) +{ + TRP_INFOREC *rec=NULL; + + /* add it to all inforecs */ + for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) { + if (TRP_SUCCESS!=trp_inforec_add_to_provenance(rec, name)) + tr_err("trp_upd_set_peer: error adding peer to provenance list."); + } +} + /* pretty print */ static void trp_inforec_route_print(TRP_INFOREC_DATA *data) { if (data->route!=NULL) { - printf(" trust_router=%.*s\n metric=%d\n interval=%d]\n", + tr_info(" trust_router=%.*s\n metric=%d\n interval=%d]\n", data->route->trust_router->len, data->route->trust_router->buf, data->route->metric, data->route->interval); } @@ -484,10 +826,9 @@ static void trp_inforec_route_print(TRP_INFOREC_DATA *data) static void trp_inforec_comm_print(TRP_INFOREC_DATA *data) { if (data->comm!=NULL) { - printf(" type=%s\n service=%s\n IdP=%s\n owner=%.*s\n contact=%.*s]\n", - tr_comm_type_to_str(data->comm->type), - (data->comm->is_service_realm)?"yes":"no", - (data->comm->is_idp_realm)?"yes":"no", + tr_info(" type=%s\n role=%s\n owner=%.*s\n contact=%.*s]\n", + tr_comm_type_to_str(data->comm->comm_type), + tr_realm_role_to_str(data->comm->role), data->comm->owner_realm->len, data->comm->owner_realm->buf, data->comm->owner_contact->len, data->comm->owner_contact->buf); /* TODO: print apcs */