From aa60420a1b690c06ae7ef9fd4584bf434cea9c6b Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Thu, 16 Jun 2016 21:49:26 -0400 Subject: [PATCH] Move TRP messaging to tr_msg.c. Fix old bug. * Move TRP message-related code to tr_msg.c * Change names/code to match existing conventions * Add constructor/destructor for TID_RESP struct * Free sub-structures when freeing TR_MSG struct * Add msgtst to Makefile.am --- Makefile.am | 17 +- common/tr_msg.c | 438 +++++++++++++++++++- include/tr_msg.h | 11 +- include/trp_internal.h | 116 +++--- include/trust_router/tid.h | 3 + include/trust_router/trp.h | 24 ++ tid/tid_resp.c | 12 + trp/msgtst.c | 21 +- trp/trp_msg.c | 977 +++++++++------------------------------------ 9 files changed, 740 insertions(+), 879 deletions(-) create mode 100644 include/trust_router/trp.h diff --git a/Makefile.am b/Makefile.am index 35d4815..eadc2df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ DISTCHECK_CONFIGURE_FLAGS = \ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) -bin_PROGRAMS= tr/trust_router tr/trpc tid/example/tidc tid/example/tids common/dh_test/tr_dh_test +bin_PROGRAMS= tr/trust_router tr/trpc tid/example/tidc tid/example/tids common/dh_test/tr_dh_test trp/msgtst AM_CPPFLAGS=-I$(srcdir)/include $(GLIB_CFLAGS) AM_CFLAGS = -Wall -Werror=missing-prototypes -Werror -Wno-parentheses $(GLIB_CFLAGS) SUBDIRS = gsscon @@ -41,6 +41,21 @@ tr/tr_trp.c tr_trpc_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS) +trp_msgtst_SOURCES = trp/msgtst.c \ +trp/trp_msg.c \ +tid/tid_req.c \ +tid/tid_resp.c \ +common/tr_name.c \ +common/tr_msg.c \ +common/tr_idp.c \ +common/tr_comm.c \ +common/tr_filter.c \ +common/tr_rp.c \ +common/tr_config.c \ +common/tr_debug.c + +trp_msgtst_LDADD = libtr_tid.la $(GLIB_LIBS) + tid_example_tidc_SOURCES = tid/example/tidc_main.c tid_example_tidc_LDADD = gsscon/libgsscon.la libtr_tid.la $(GLIB_LIBS) diff --git a/common/tr_msg.c b/common/tr_msg.c index f68c5d1..0d55ebe 100644 --- a/common/tr_msg.c +++ b/common/tr_msg.c @@ -44,9 +44,50 @@ #include #include #include +#include #include #include +/* JSON helpers */ +/* Read attribute attr from msg as an integer. Returns nonzero on error. */ +static int tr_msg_get_json_integer(json_t *jmsg, const char *attr, int *dest) +{ + json_t *obj; + + obj=json_object_get(jmsg, attr); + if (obj == NULL) { + return -1; + } + /* check type */ + if (!json_is_integer(obj)) { + return -1; + } + + (*dest)=json_integer_value(obj); + return 0; +} + +/* 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) +{ + json_t *obj; + + obj=json_object_get(jmsg, attr); + if (obj == NULL) + return -1; + + /* check type */ + if (!json_is_string(obj)) + return -1; + + *dest=talloc_strdup(mem_ctx, json_string_value(obj)); + if (*dest==NULL) + return -1; + + return 0; +} + enum msg_type tr_msg_get_msg_type(TR_MSG *msg) { return msg->msg_type; @@ -83,6 +124,32 @@ void tr_msg_set_resp(TR_MSG *msg, TID_RESP *resp) msg->msg_type = TID_RESPONSE; } +TRP_UPD *tr_msg_get_trp_upd(TR_MSG *msg) +{ + if (msg->msg_type == TRP_UPDATE) + return (TRP_UPD *)msg->msg_rep; + return NULL; +} + +void tr_msg_set_trp_upd(TR_MSG *msg, TRP_UPD *update) +{ + msg->msg_rep=update; + msg->msg_type=TRP_UPDATE; +} + +TRP_REQ *tr_msg_get_trp_req(TR_MSG *msg) +{ + if (msg->msg_type == TRP_REQUEST) + return (TRP_REQ *)msg->msg_rep; + return NULL; +} + +void tr_msg_set_trp_req(TR_MSG *msg, TRP_REQ *req) +{ + msg->msg_rep=req; + msg->msg_type=TRP_REQUEST; +} + static json_t *tr_msg_encode_dh(DH *dh) { json_t *jdh = NULL; @@ -411,7 +478,7 @@ static TID_RESP *tr_msg_decode_tidresp(json_t *jresp) json_t *jservers = NULL; json_t *jerr_msg = NULL; - if (!(tresp = talloc_zero(NULL, TID_RESP))) { + if (!(tresp=tid_resp_new(NULL))) { tr_crit("tr_msg_decode_tidresp(): Error allocating TID_RESP structure."); return NULL; } @@ -465,6 +532,331 @@ static TID_RESP *tr_msg_decode_tidresp(json_t *jresp) return tresp; } + +/* Information records for TRP update msg + * requires that jrec already be allocated */ +static TRP_RC tr_msg_encode_inforec_route(json_t *jrec, TRP_INFOREC_DATA rec_data) +{ + TRP_INFOREC_ROUTE *route=rec_data.route; + json_t *jstr=NULL; + json_t *jint=NULL; + char *s=NULL; + + if (route==NULL) + return TRP_BADTYPE; + + s=tr_name_strdup(route->comm); + if (s==NULL) + return TRP_NOMEM; + jstr=json_string(s); + free(s);s=NULL; + if(jstr==NULL) + return TRP_ERROR; + json_object_set_new(jrec, "community", jstr); + + s=tr_name_strdup(route->realm); + if (s==NULL) + return TRP_NOMEM; + jstr=json_string(s); + free(s);s=NULL; + if(jstr==NULL) + return TRP_ERROR; + json_object_set_new(jrec, "realm", jstr); + + s=tr_name_strdup(route->trust_router); + if (s==NULL) + return TRP_NOMEM; + jstr=json_string(s); + free(s);s=NULL; + if(jstr==NULL) + return TRP_ERROR; + json_object_set_new(jrec, "trust_router", jstr); + + jint=json_integer(route->metric); + if(jint==NULL) + return TRP_ERROR; + json_object_set_new(jrec, "metric", jint); + + jint=json_integer(route->interval); + if(jint==NULL) + return TRP_ERROR; + json_object_set_new(jrec, "interval", jint); + + return TRP_SUCCESS; +} + +static json_t *tr_msg_encode_inforec(TRP_INFOREC *rec) +{ + json_t *jrec=NULL; + json_t *jstr=NULL; + + if ((rec==NULL) || (rec->type==TRP_INFOREC_TYPE_UNKNOWN)) + return NULL; + + jrec=json_object(); + if (jrec==NULL) + return NULL; + + jstr=json_string(trp_inforec_type_to_string(rec->type)); + if (jstr==NULL) { + json_decref(jrec); + return NULL; + } + json_object_set_new(jrec, "record_type", jstr); + + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (TRP_SUCCESS!=tr_msg_encode_inforec_route(jrec, rec->data)) { + json_decref(jrec); + return NULL; + } + break; + default: + json_decref(jrec); + return NULL; + } + return jrec; +} + +/* decode a single record */ +static TRP_INFOREC *tr_msg_decode_trp_inforec(TALLOC_CTX *mem_ctx, json_t *jrecord) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + TRP_INFOREC_TYPE rectype; + TRP_INFOREC *rec=NULL; + TRP_RC rc=TRP_ERROR; + char *s=NULL; + int num=0; + + if (0!=tr_msg_get_json_string(jrecord, "record_type", &s, tmp_ctx)) + goto cleanup; + + rectype=trp_inforec_type_from_string(s); + talloc_free(s); s=NULL; + + rec=trp_inforec_new(tmp_ctx, rectype); + if (rec==NULL) { + rc=TRP_NOMEM; + goto cleanup; + } + + /* We only support route_info records for now*/ + if (rec->type!=TRP_INFOREC_TYPE_ROUTE) { + rc=TRP_UNSUPPORTED; + goto cleanup; + } + + tr_debug("tr_msg_decode_trp_inforec: '%s' record found.", trp_inforec_type_to_string(rec->type)); + + rc=tr_msg_get_json_string(jrecord, "community", &s, tmp_ctx); + if (rc != TRP_SUCCESS) + goto cleanup; + if (TRP_SUCCESS!=trp_inforec_set_comm(rec, tr_new_name(s))) + goto cleanup; + talloc_free(s); s=NULL; + + rc=tr_msg_get_json_string(jrecord, "realm", &s, tmp_ctx); + if (rc != TRP_SUCCESS) + goto cleanup; + if (TRP_SUCCESS!=trp_inforec_set_realm(rec, tr_new_name(s))) /* assumes route_info */ + goto cleanup; + talloc_free(s); s=NULL; + + rc=tr_msg_get_json_string(jrecord, "trust_router", &s, tmp_ctx); + if (rc != TRP_SUCCESS) + goto cleanup; + if (TRP_SUCCESS!=trp_inforec_set_trust_router(rec, tr_new_name(s))) /* assumes route_info */ + goto cleanup; + talloc_free(s); s=NULL; + + rc=tr_msg_get_json_integer(jrecord, "metric", &num); + if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_inforec_set_metric(rec,num))) + goto cleanup; + + rc=tr_msg_get_json_integer(jrecord, "interval", &num); + if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_inforec_set_interval(rec,num))) + goto cleanup; + + talloc_steal(mem_ctx, rec); + rc=TRP_SUCCESS; + +cleanup: + if (rc != TRP_SUCCESS) { + trp_inforec_free(rec); + rec=NULL; + } + talloc_free(tmp_ctx); + return rec; +} + +/* TRP update msg */ +static json_t *tr_msg_encode_trp_upd(TRP_UPD *update) +{ + json_t *jupdate=NULL; + json_t *jrecords=NULL; + json_t *jrec=NULL; + TRP_INFOREC *rec; + + if (update==NULL) + return NULL; + + jupdate=json_object(); + if (jupdate==NULL) + return NULL; + + jrecords=json_array(); + if (jrecords==NULL) { + json_decref(jupdate); + return NULL; + } + json_object_set_new(jupdate, "records", jrecords); /* jrecords now a "borrowed" reference */ + for (rec=update->records; rec!=NULL; rec=rec->next) { + jrec=tr_msg_encode_inforec(rec); + if (jrec==NULL) { + json_decref(jupdate); /* also decs jrecords and any elements */ + return NULL; + } + if (0!=json_array_append_new(jrecords, jrec)) { + json_decref(jupdate); /* also decs jrecords and any elements */ + json_decref(jrec); /* this one did not get added so dec explicitly */ + return NULL; + } + } + + return jupdate; +} + +/*Creates a linked list of records in the msg->body talloc context. + * An error will be returned if any unparseable records are encountered. + */ +static TRP_UPD *tr_msg_decode_trp_upd(TALLOC_CTX *mem_ctx, json_t *jupdate) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + json_t *jrecords=NULL; + size_t ii=0; + TRP_UPD *update=NULL; + TRP_INFOREC *new_rec=NULL; + TRP_INFOREC *list_tail=NULL; + TRP_RC rc=TRP_ERROR; + + update=trp_upd_new(tmp_ctx); + if (update==NULL) { + rc=TRP_NOMEM; + goto cleanup; + } + + jrecords=json_object_get(jupdate, "records"); + if ((jrecords==NULL) || (!json_is_array(jrecords))) { + rc=TRP_NOPARSE; + goto cleanup; + } + + tr_debug("tr_msg_decode_trp_upd: found %d records", json_array_size(jrecords)); + /* process the array */ + for (ii=0; iirecords=new_rec; /* first is a special case */ + else + list_tail->next=new_rec; + + list_tail=new_rec; + } + + /* Succeeded. Move new allocations into the correct talloc context */ + talloc_steal(mem_ctx, update); + rc=TRP_SUCCESS; + +cleanup: + talloc_free(tmp_ctx); + if (rc!=TRP_SUCCESS) + return NULL; + return update; +} + +static json_t *tr_msg_encode_trp_req(TRP_REQ *req) +{ + json_t *jbody=NULL; + json_t *jstr=NULL; + char *s=NULL; + + if (req==NULL) + return NULL; + + jbody=json_object(); + if (jbody==NULL) + return NULL; + + s=tr_name_strdup(req->comm); /* ensures null termination */ + if (s==NULL) { + json_decref(jbody); + return NULL; + } + jstr=json_string(s); + free(s); s=NULL; + if (jstr==NULL) { + json_decref(jbody); + return NULL; + } + json_object_set_new(jbody, "community", jstr); + + s=tr_name_strdup(req->realm); /* ensures null termination */ + if (s==NULL) { + json_decref(jbody); + return NULL; + } + jstr=json_string(s); + free(s); s=NULL; + if (jstr==NULL) { + json_decref(jbody); + return NULL; + } + json_object_set_new(jbody, "realm", jstr); + + return jbody; +} + +static TRP_REQ *tr_msg_decode_trp_req(TALLOC_CTX *mem_ctx, json_t *jreq) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + TRP_REQ *req=NULL; + char *s=NULL; + TRP_RC rc=TRP_ERROR; + + /* check message type and body type for agreement */ + req=trp_req_new(tmp_ctx); + if (req==NULL) { + rc=TRP_NOMEM; + goto cleanup; + } + + rc=tr_msg_get_json_string(jreq, "community", &s, tmp_ctx); + if (rc!=TRP_SUCCESS) + goto cleanup; + req->comm=tr_new_name(s); + talloc_free(s); s=NULL; + + rc=tr_msg_get_json_string(jreq, "realm", &s, tmp_ctx); + if (rc!=TRP_SUCCESS) + goto cleanup; + req->realm=tr_new_name(s); + talloc_free(s); s=NULL; + + rc=TRP_SUCCESS; + talloc_steal(mem_ctx, req); + +cleanup: + talloc_free(tmp_ctx); + if (rc!=TRP_SUCCESS) + return NULL; + return req; +} + char *tr_msg_encode(TR_MSG *msg) { json_t *jmsg; @@ -488,7 +880,17 @@ char *tr_msg_encode(TR_MSG *msg) json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidresp(tr_msg_get_resp(msg))); break; - /* TBD -- Add TR message types */ + case TRP_UPDATE: + jmsg_type = json_string("trp_update"); + json_object_set_new(jmsg, "msg_type", jmsg_type); + json_object_set_new(jmsg, "msg_body", tr_msg_encode_trp_upd(tr_msg_get_trp_upd(msg))); + break; + + case TRP_REQUEST: + jmsg_type = json_string("trp_request"); + json_object_set_new(jmsg, "msg_type", jmsg_type); + json_object_set_new(jmsg, "msg_body", tr_msg_encode_trp_req(tr_msg_get_trp_req(msg))); + break; default: json_decref(jmsg); @@ -502,11 +904,11 @@ char *tr_msg_encode(TR_MSG *msg) TR_MSG *tr_msg_decode(char *jbuf, size_t buflen) { - TR_MSG *msg; + TR_MSG *msg=NULL; json_t *jmsg = NULL; json_error_t rc; - json_t *jtype; - json_t *jbody; + json_t *jtype=NULL; + json_t *jbody=NULL; const char *mtype = NULL; if (NULL == (jmsg = json_loadb(jbuf, buflen, JSON_DISABLE_EOF_CHECK, &rc))) { @@ -540,6 +942,14 @@ TR_MSG *tr_msg_decode(char *jbuf, size_t buflen) msg->msg_type = TID_RESPONSE; tr_msg_set_resp(msg, tr_msg_decode_tidresp(jbody)); } + else if (0 == strcmp(mtype, "trp_update")) { + msg->msg_type = TRP_UPDATE; + tr_msg_set_trp_upd(msg, tr_msg_decode_trp_upd(NULL, jbody)); /* null talloc context for now */ + } + else if (0 == strcmp(mtype, "trp_request")) { + msg->msg_type = TRP_UPDATE; + tr_msg_set_trp_req(msg, tr_msg_decode_trp_req(NULL, jbody)); /* null talloc context for now */ + } else { msg->msg_type = TR_UNKNOWN; msg->msg_rep = NULL; @@ -555,8 +965,24 @@ void tr_msg_free_encoded(char *jmsg) void tr_msg_free_decoded(TR_MSG *msg) { - if (msg) + if (msg) { + switch (msg->msg_type) { + case TID_REQUEST: + tid_req_free(tr_msg_get_req(msg)); + break; + case TID_RESPONSE: + tid_resp_free(tr_msg_get_resp(msg)); + break; + case TRP_UPDATE: + trp_upd_free(tr_msg_get_trp_upd(msg)); + break; + case TRP_REQUEST: + trp_req_free(tr_msg_get_trp_req(msg)); + default: + break; + } free (msg); + } } diff --git a/include/tr_msg.h b/include/tr_msg.h index 4f208e5..0a9096f 100644 --- a/include/tr_msg.h +++ b/include/tr_msg.h @@ -37,13 +37,15 @@ #include #include - +#include typedef struct tr_msg TR_MSG; enum msg_type { TR_UNKNOWN = 0, TID_REQUEST, - TID_RESPONSE + TID_RESPONSE, + TRP_UPDATE, + TRP_REQUEST }; /* Union of TR message types to hold message of any type. */ @@ -59,6 +61,11 @@ TID_REQ *tr_msg_get_req(TR_MSG *msg); void tr_msg_set_req(TR_MSG *msg, TID_REQ *req); TID_RESP *tr_msg_get_resp(TR_MSG *msg); void tr_msg_set_resp(TR_MSG *msg, TID_RESP *resp); +TRP_UPD *tr_msg_get_trp_upd(TR_MSG *msg); +void tr_msg_set_trp_upd(TR_MSG *msg, TRP_UPD *req); +TRP_REQ *tr_msg_get_trp_req(TR_MSG *msg); +void tr_msg_set_trp_req(TR_MSG *msg, TRP_REQ *req); + /* Encoders/Decoders */ char *tr_msg_encode(TR_MSG *msg); diff --git a/include/trp_internal.h b/include/trp_internal.h index f167fdc..dab0140 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -5,92 +5,72 @@ #include #include - -#define TRP_PORT 12310 -#define TRP_METRIC_INFINITY 0xFFFF -#define TRP_METRIC_INVALID 0xFFFFFFFF -#define TRP_INTERVAL_INVALID 0 - -typedef enum trp_rc { - TRP_SUCCESS=0, - TRP_ERROR, /* generic error */ - TRP_NOPARSE, /* parse error */ - TRP_NOMEM, /* allocation error */ - TRP_BADTYPE, /* typing error */ - TRP_UNSUPPORTED, /* unsupported feature */ -} TRP_RC; - -/*** Messages ***/ -typedef enum trp_msg_type { - TRP_MSG_TYPE_UNKNOWN=0, /* conveniently, JSON parser returns 0 if a non-integer number is specified */ - TRP_MSG_TYPE_UPDATE, - TRP_MSG_TYPE_ROUTE_REQ -} TRP_MSG_TYPE; +#include /* info records */ -typedef enum trp_msg_info_type { - TRP_MSG_INFO_TYPE_UNKNOWN=0, /* conveniently, JSON parser returns 0 if a non-integer number is specified */ - TRP_MSG_INFO_TYPE_ROUTE, - TRP_MSG_INFO_TYPE_COMMUNITY, /* not yet implemented (2016-06-14) */ -} TRP_MSG_INFO_TYPE; - -typedef struct trp_msg { - TRP_MSG_TYPE type; - void *body; -} TRP_MSG; - -/* update msg record types */ -typedef struct trp_msg_info_rec TRP_MSG_INFO_REC; -struct trp_msg_info_rec { - TRP_MSG_INFO_REC *next; - TRP_MSG_INFO_TYPE type; - void *data; /* pointer to one of the record types */ -}; - -typedef struct trp_msg_info_route { +typedef enum trp_inforec_type { + TRP_INFOREC_TYPE_UNKNOWN=0, /* conveniently, JSON parser returns 0 if a non-integer number is specified */ + TRP_INFOREC_TYPE_ROUTE, + TRP_INFOREC_TYPE_COMMUNITY, /* not yet implemented (2016-06-14) */ +} TRP_INFOREC_TYPE; + +/* TRP update record types */ +typedef struct trp_inforec_route { TR_NAME *comm; TR_NAME *realm; TR_NAME *trust_router; unsigned int metric; unsigned int interval; -} TRP_MSG_INFO_ROUTE; +} TRP_INFOREC_ROUTE; /* TODO: define struct trp_msg_info_community */ -typedef struct trp_route_update { - void *records; -} TRP_ROUTE_UPDATE; +typedef union trp_inforec_data { + TRP_INFOREC_ROUTE *route; + /* TRP_INFOREC_COMM *comm; */ +} TRP_INFOREC_DATA; -typedef struct trp_route_req { +typedef struct trp_inforec TRP_INFOREC; +struct trp_inforec { + TRP_INFOREC *next; + TRP_INFOREC_TYPE type; + TRP_INFOREC_DATA data; /* contains pointer to one of the record types */ +}; + +struct trp_update { + TRP_INFOREC *records; +}; + +struct trp_req { TR_NAME *comm; TR_NAME *realm; -} TRP_ROUTE_REQ; - -TRP_MSG_TYPE trp_msg_type_from_string(const char *s); -const char *trp_msg_type_to_string(TRP_MSG_TYPE msgtype); -TRP_MSG_INFO_TYPE trp_msg_info_type_from_string(const char *s); -const char *trp_msg_info_type_to_string(TRP_MSG_INFO_TYPE msgtype); +}; -TRP_MSG *trp_msg_new(TALLOC_CTX *mem_ctx); -void trp_msg_destroy(TRP_MSG *msg); -void trp_msg_pprint(TRP_MSG *msg); -char *trp_encode_msg(TRP_MSG *msg); +TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s); +const char *trp_inforec_type_to_string(TRP_INFOREC_TYPE msgtype); + +TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx); +void trp_upd_free(TRP_UPD *update); +TRP_REQ *trp_req_new(TALLOC_CTX *mem_ctx); +void trp_req_free(TRP_REQ *req); +TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type); +void trp_inforec_free(TRP_INFOREC *rec); +TR_NAME *trp_inforec_get_comm(TRP_INFOREC *rec); +TRP_RC trp_inforec_set_comm(TRP_INFOREC *rec, TR_NAME *comm); +TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec); +TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm); +TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec); +TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router); +unsigned int trp_inforec_get_metric(TRP_INFOREC *rec); +TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric); +unsigned int trp_inforec_get_interval(TRP_INFOREC *rec); +TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval); -TR_NAME *trp_msg_info_route_get_comm(TRP_MSG_INFO_REC *rec); -TR_NAME *trp_msg_info_route_get_realm(TRP_MSG_INFO_REC *rec); -TR_NAME *trp_msg_info_route_get_trust_router(TRP_MSG_INFO_REC *rec); -unsigned int trp_msg_info_route_get_metric(TRP_MSG_INFO_REC *rec); -unsigned int trp_msg_info_route_get_interval(TRP_MSG_INFO_REC *rec); typedef struct trps_instance TRPS_INSTANCE; -/* REMOVE THIS!! --jennifer, 2016-06-13 */ -typedef TRP_MSG TRP_REQ; -typedef TRP_MSG TRP_RESP; - - -typedef int (TRPS_REQ_FUNC)(TRPS_INSTANCE *, TRP_REQ *, TRP_RESP *, void *); -typedef void (TRPS_RESP_FUNC)(TRPS_INSTANCE *, TRP_REQ *, TRP_RESP *, void *); +typedef int (TRPS_REQ_FUNC)(); +typedef void (TRPS_RESP_FUNC)(); typedef int (trps_auth_func)(gss_name_t client_name, TR_NAME *display_name, void *cookie); diff --git a/include/trust_router/tid.h b/include/trust_router/tid.h index 613541f..88c1a38 100644 --- a/include/trust_router/tid.h +++ b/include/trust_router/tid.h @@ -103,6 +103,9 @@ TR_EXPORT TID_REQ *tid_dup_req (TID_REQ *orig_req); void TR_EXPORT tid_req_free( TID_REQ *req); /* Utility functions for TID_RESP structure, in tid/tid_resp.c */ + +TID_RESP *tid_resp_new(TALLOC_CTX *mem_ctx); +void tid_resp_free(TID_RESP *resp); TR_EXPORT int tid_resp_get_result(TID_RESP *resp); void tid_resp_set_result(TID_RESP *resp, int result); TR_EXPORT TR_NAME *tid_resp_get_err_msg(TID_RESP *resp); diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h new file mode 100644 index 0000000..e160543 --- /dev/null +++ b/include/trust_router/trp.h @@ -0,0 +1,24 @@ +#ifndef TRP_H +#define TRP_H + +#include + +#define TRP_PORT 12310 +#define TRP_METRIC_INFINITY 0xFFFF +#define TRP_METRIC_INVALID 0xFFFFFFFF +#define TRP_INTERVAL_INVALID 0 + +typedef enum trp_rc { + TRP_SUCCESS=0, + TRP_ERROR, /* generic error */ + TRP_NOPARSE, /* parse error */ + TRP_NOMEM, /* allocation error */ + TRP_BADTYPE, /* typing error */ + TRP_UNSUPPORTED, /* unsupported feature */ +} TRP_RC; + + +typedef struct trp_update TRP_UPD; +typedef struct trp_req TRP_REQ; + +#endif /* TRP_H */ diff --git a/tid/tid_resp.c b/tid/tid_resp.c index 2611b3b..44a866a 100644 --- a/tid/tid_resp.c +++ b/tid/tid_resp.c @@ -35,9 +35,21 @@ #include #include #include +#include #include +TID_RESP *tid_resp_new(TALLOC_CTX *mem_ctx) +{ + return talloc(mem_ctx, TID_RESP); +} + +void tid_resp_free(TID_RESP *resp) +{ + if (resp) + talloc_free(resp); +} + TR_EXPORT int tid_resp_get_result(TID_RESP *resp) { return(resp->result); diff --git a/trp/msgtst.c b/trp/msgtst.c index 5622e3a..aef0c19 100644 --- a/trp/msgtst.c +++ b/trp/msgtst.c @@ -1,11 +1,12 @@ /* Testing trp message encoding / decoding */ -/* compiles with: gcc -o msgtst -I../include -I../include/trust_router msgtst.c trp_msg.c $(pkg-config --cflags --libs glib-2.0) ../common/tr_debug.c ../common/tr_name.c -ltalloc -ljansson */ +/* compiles with: gcc -o msgtst -I../include msgtst.c trp_msg.c $(pkg-config --cflags --libs glib-2.0) ../common/tr_debug.c ../common/tr_name.c ../common/tr_msg.c -ltalloc -ljansson */ #include #include -#include +#include +#include #include #define MAX_MSG_LEN 8192 @@ -16,8 +17,7 @@ int main(int argc, const char *argv[]) FILE *f; char *buf; size_t buflen; - TRP_RC rc; - TRP_MSG *msg; + TR_MSG *msg; if (argc != 2) { printf("Usage: %s \n\n", argv[0]); @@ -47,21 +47,16 @@ int main(int argc, const char *argv[]) if (buflen>=MAX_MSG_LEN) printf("Warning: file may exceed maximum message length (%d bytes).\n", MAX_MSG_LEN); - rc=trp_parse_msg(main_ctx, buf, buflen, &msg); - printf("trp_parse_msg returned %d\n\n", rc); + msg=tr_msg_decode(buf, buflen); - if (rc==TRP_SUCCESS) - trp_msg_print(msg); +/* if (rc==TRP_SUCCESS) + trp_msg_print(msg);*/ printf("\nEncoding...\n"); - printf("Result: \n%s\n\n", trp_encode_msg(msg)); + printf("Result: \n%s\n\n", tr_msg_encode(msg)); talloc_report_full(main_ctx, stdout); - if (rc==TRP_SUCCESS) - talloc_free(msg); - - talloc_report_full(main_ctx, stdout); return 0; } diff --git a/trp/trp_msg.c b/trp/trp_msg.c index 304d7fe..0545fc4 100644 --- a/trp/trp_msg.c +++ b/trp/trp_msg.c @@ -1,92 +1,35 @@ #include #include -#include +#include #include #include /* static prototypes */ -static void *trp_route_update_new(TALLOC_CTX *mem_ctx); -static json_t *trp_encode_route_update(void *req_in); -static TRP_RC trp_parse_route_update(TRP_MSG *msg, json_t *jmsg); -static void trp_route_update_print(void *); - -static void *trp_route_req_new(TALLOC_CTX *mem_ctx); -static json_t *trp_encode_route_req(void *req_in); -static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jmsg); -static void trp_route_req_print(void *); - -static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx); -static TRP_RC trp_encode_info_route(json_t *jrec, void *route_in); -static TRP_RC trp_parse_info_route(TRP_MSG *msg, json_t *jmsg); -static void trp_msg_info_route_print(void *); - -/* table of string names for TMT_MSG_TYPE codes */ -struct trp_msg_type_entry { - const char *name; - TRP_MSG_TYPE type; - void *(*allocate)(TALLOC_CTX *); - json_t *(*encode)(void *); - TRP_RC (*parse)(TRP_MSG *, json_t *); - void (*print)(void *); -}; -static struct trp_msg_type_entry trp_msg_type_table[] = { - { "update", TRP_MSG_TYPE_UPDATE, trp_route_update_new, trp_encode_route_update, trp_parse_route_update, trp_route_update_print }, - { "route_req", TRP_MSG_TYPE_ROUTE_REQ, trp_route_req_new, trp_encode_route_req, trp_parse_route_req, trp_route_req_print }, - { NULL, TRP_MSG_TYPE_UNKNOWN, NULL, NULL, NULL, NULL } /* must be the last entry */ -}; +static void *trp_inforec_route_new(TALLOC_CTX *mem_ctx); +static void trp_inforec_route_print(TRP_INFOREC_DATA); + -struct trp_msg_info_type_entry { +struct trp_inforec_type_entry { const char *name; - TRP_MSG_INFO_TYPE type; + TRP_INFOREC_TYPE type; void *(*allocate)(TALLOC_CTX *); - TRP_RC (*encode)(json_t *, void *); - void (*print)(void *); + void (*print)(TRP_INFOREC_DATA); }; -static struct trp_msg_info_type_entry trp_msg_info_type_table[] = { - { "route_info", TRP_MSG_INFO_TYPE_ROUTE, trp_msg_info_route_new, trp_encode_info_route, trp_msg_info_route_print }, - { "comm_info", TRP_MSG_INFO_TYPE_COMMUNITY, NULL, NULL, NULL }, - { NULL, TRP_MSG_INFO_TYPE_UNKNOWN, NULL, NULL, NULL } /* must be the last entry */ +static struct trp_inforec_type_entry trp_inforec_type_table[] = { + { "route", TRP_INFOREC_TYPE_ROUTE, trp_inforec_route_new, trp_inforec_route_print }, + { "comm", TRP_INFOREC_TYPE_COMMUNITY, NULL, NULL }, + { NULL, TRP_INFOREC_TYPE_UNKNOWN, NULL, NULL } /* must be the last entry */ }; -/* Use talloc's dynamic type checking to verify type. - * By default, this will cause program abort, but can be overridden - * via talloc_set_abort_fn() if more graceful handling is needed. */ -static void msg_body_type_check(TRP_MSG_TYPE msgtype, void *p) -{ - switch (msgtype) { - case TRP_MSG_TYPE_UPDATE: - talloc_get_type_abort(p, TRP_ROUTE_UPDATE); - break; - - case TRP_MSG_TYPE_ROUTE_REQ: - talloc_get_type_abort(p, TRP_ROUTE_REQ); - break; - default: - break; - } -} - -/* look up an entry in the trp_msg_type_table */ -static struct trp_msg_type_entry *get_trp_msg_type_entry(TRP_MSG_TYPE msgtype) +/* look up an entry in the trp_inforec_type_table */ +static struct trp_inforec_type_entry *get_trp_inforec_type_entry(TRP_INFOREC_TYPE msgtype) { - struct trp_msg_type_entry *entry=trp_msg_type_table; + struct trp_inforec_type_entry *entry=trp_inforec_type_table; - while ((entry->type != TRP_MSG_TYPE_UNKNOWN) - && (entry->type != msgtype)) { - entry ++; - } - return entry; -} - -/* look up an entry in the trp_msg_info_type_table */ -static struct trp_msg_info_type_entry *get_trp_msg_info_type_entry(TRP_MSG_INFO_TYPE msgtype) -{ - struct trp_msg_info_type_entry *entry=trp_msg_info_type_table; - - while ((entry->type != TRP_MSG_INFO_TYPE_UNKNOWN) + while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN) && (entry->type != msgtype)) { entry ++; } @@ -94,11 +37,11 @@ static struct trp_msg_info_type_entry *get_trp_msg_info_type_entry(TRP_MSG_INFO_ } /* translate strings to codes */ -TRP_MSG_TYPE trp_msg_type_from_string(const char *s) +TRP_INFOREC_TYPE trp_inforec_type_from_string(const char *s) { - struct trp_msg_type_entry *entry=trp_msg_type_table; + struct trp_inforec_type_entry *entry=trp_inforec_type_table; - while ((entry->type != TRP_MSG_TYPE_UNKNOWN) + while ((entry->type != TRP_INFOREC_TYPE_UNKNOWN) && (strcmp(s, entry->name)!=0)) { entry++; } @@ -106,121 +49,41 @@ TRP_MSG_TYPE trp_msg_type_from_string(const char *s) } /* translate codes to strings (do not need to be freed) * Returns NULL on an unknown code */ -const char *trp_msg_type_to_string(TRP_MSG_TYPE msgtype) +const char *trp_inforec_type_to_string(TRP_INFOREC_TYPE msgtype) { - struct trp_msg_type_entry *entry=get_trp_msg_type_entry(msgtype); + struct trp_inforec_type_entry *entry=get_trp_inforec_type_entry(msgtype); return entry->name; } -/* translate strings to codes */ -TRP_MSG_INFO_TYPE trp_msg_info_type_from_string(const char *s) -{ - struct trp_msg_info_type_entry *entry=trp_msg_info_type_table; - - while ((entry->type != TRP_MSG_INFO_TYPE_UNKNOWN) - && (strcmp(s, entry->name)!=0)) { - entry++; - } - return entry->type; -} -/* translate codes to strings (do not need to be freed) - * Returns NULL on an unknown code */ -const char *trp_msg_info_type_to_string(TRP_MSG_INFO_TYPE msgtype) -{ - struct trp_msg_info_type_entry *entry=get_trp_msg_info_type_entry(msgtype); - return entry->name; -} - - -TRP_MSG *trp_msg_new(TALLOC_CTX *mem_ctx) -{ - TRP_MSG *new_msg=talloc(mem_ctx, TRP_MSG); - - if (new_msg != NULL) { - new_msg->type=TRP_MSG_INFO_TYPE_UNKNOWN; - new_msg->body=NULL; - } - return new_msg; -} - -void trp_msg_destroy(TRP_MSG *msg) -{ - if (msg) - talloc_free(msg); -} - - -/* JSON helpers */ -/* Read attribute attr from msg as an integer */ -static TRP_RC trp_get_json_integer(json_t *jmsg, const char *attr, int *dest) -{ - json_error_t err; - json_t *obj; - - obj=json_object_get(jmsg, attr); - if (obj == NULL) { - return TRP_NOPARSE; - } - /* check type */ - if (!json_is_integer(obj)) { - return TRP_BADTYPE; - } - - (*dest)=json_integer_value(obj); - return TRP_SUCCESS; -} - -/* Read attribute attr from msg as a string. Copies string into mem_ctx context so jmsg can - * be destroyed safely. */ -static TRP_RC trp_get_json_string(json_t *jmsg, const char *attr, char **dest, TALLOC_CTX *mem_ctx) -{ - json_error_t err; - json_t *obj; - - obj=json_object_get(jmsg, attr); - if (obj == NULL) - return TRP_NOPARSE; - - /* check type */ - if (!json_is_string(obj)) - return TRP_BADTYPE; - - *dest=talloc_strdup(mem_ctx, json_string_value(obj)); - if (*dest==NULL) - return TRP_NOMEM; - - return TRP_SUCCESS; -} - /* called by talloc when destroying an update message body */ -static int trp_msg_info_route_destructor(void *object) +static int trp_inforec_route_destructor(void *object) { - TRP_MSG_INFO_ROUTE *body=talloc_get_type_abort(object, TRP_MSG_INFO_ROUTE); + TRP_INFOREC_ROUTE *body=talloc_get_type_abort(object, TRP_INFOREC_ROUTE); /* clean up TR_NAME data, which are not managed by talloc */ if (body->comm != NULL) { tr_free_name(body->comm); body->comm=NULL; - tr_debug("trp_msg_info_route_destructor: freed community"); + tr_debug("trp_inforec_route_destructor: freed community"); } if (body->realm != NULL) { tr_free_name(body->realm); body->realm=NULL; - tr_debug("trp_msg_info_route_destructor: freed realm"); + tr_debug("trp_inforec_route_destructor: freed realm"); } if (body->trust_router != NULL) { tr_free_name(body->trust_router); body->trust_router=NULL; - tr_debug("trp_msg_info_route_destructor: freed trust_router"); + tr_debug("trp_inforec_route_destructor: freed trust_router"); } return 0; } -static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx) +static void *trp_inforec_route_new(TALLOC_CTX *mem_ctx) { - TRP_MSG_INFO_ROUTE *new_rec=talloc(mem_ctx, TRP_MSG_INFO_ROUTE); + TRP_INFOREC_ROUTE *new_rec=talloc(mem_ctx, TRP_INFOREC_ROUTE); if (new_rec != NULL) { new_rec->comm=NULL; @@ -228,720 +91,256 @@ static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx) new_rec->trust_router=NULL; new_rec->metric=TRP_METRIC_INFINITY; new_rec->interval=0; - talloc_set_destructor((void *)new_rec, trp_msg_info_route_destructor); + talloc_set_destructor((void *)new_rec, trp_inforec_route_destructor); } return new_rec; } -TR_NAME *trp_msg_info_route_get_comm(TRP_MSG_INFO_REC *rec) +TR_NAME *trp_inforec_get_comm(TRP_INFOREC *rec) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) - return route->comm; - else - return NULL; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) + return rec->data.route->comm; + break; + default: + break; + } + return NULL; } -TRP_RC trp_msg_info_route_set_comm(TRP_MSG_INFO_REC *rec, TR_NAME *comm) +TRP_RC trp_inforec_set_comm(TRP_INFOREC *rec, TR_NAME *comm) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) { - route->comm=comm; - return TRP_SUCCESS; - } else - return TRP_BADTYPE; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) { + rec->data.route->comm=comm; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; } -TR_NAME *trp_msg_info_route_get_realm(TRP_MSG_INFO_REC *rec) +TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) - return route->realm; - else - return NULL; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) + return rec->data.route->realm; + break; + default: + break; + } + return NULL; } -TRP_RC trp_msg_info_route_set_realm(TRP_MSG_INFO_REC *rec, TR_NAME *realm) +TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) { - route->realm=realm; - return TRP_SUCCESS; - } else - return TRP_BADTYPE; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) { + rec->data.route->realm=realm; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; } -TR_NAME *trp_msg_info_route_get_trust_router(TRP_MSG_INFO_REC *rec) +TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) - return route->trust_router; - else - return NULL; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) + return rec->data.route->trust_router; + break; + default: + break; + } + return NULL; } -TRP_RC trp_msg_info_route_set_trust_router(TRP_MSG_INFO_REC *rec, TR_NAME *trust_router) +TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) { - route->trust_router=trust_router; - return TRP_SUCCESS; - } else - return TRP_BADTYPE; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) { + rec->data.route->trust_router=trust_router; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; +} + +unsigned int trp_inforec_get_metric(TRP_INFOREC *rec) +{ + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) + return rec->data.route->metric; + break; + default: + break; + } + return TRP_METRIC_INVALID; } -unsigned int trp_msg_info_route_get_metric(TRP_MSG_INFO_REC *rec) +TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) - return route->metric; - else - return TRP_METRIC_INVALID; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) { + rec->data.route->metric=metric; + return TRP_SUCCESS; + } + break; + default: + break; + } + return TRP_ERROR; } -TRP_RC trp_msg_info_route_set_metric(TRP_MSG_INFO_REC *rec, unsigned int metric) +unsigned int trp_inforec_get_interval(TRP_INFOREC *rec) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) { - route->metric=metric; - return TRP_SUCCESS; - } else - return TRP_BADTYPE; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) + return rec->data.route->interval; + break; + default: + break; + } + return TRP_INTERVAL_INVALID; } -unsigned int trp_msg_info_route_get_interval(TRP_MSG_INFO_REC *rec) +TRP_RC trp_inforec_set_interval(TRP_INFOREC *rec, unsigned int interval) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) - return route->interval; - else - return TRP_INTERVAL_INVALID; + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + if (rec->data.route!=NULL) { + rec->data.route->interval=interval; + return TRP_SUCCESS; + default: + break; + } + break; + } + return TRP_ERROR; } -TRP_RC trp_msg_info_route_set_interval(TRP_MSG_INFO_REC *rec, unsigned int interval) +/* for internal use only; must set rec->type before calling this */ +static TRP_RC trp_inforec_set_data(TRP_INFOREC *rec, void *data) { - TRP_MSG_INFO_ROUTE *route=talloc_get_type(rec->data, TRP_MSG_INFO_ROUTE); - if ((rec->type==TRP_MSG_INFO_TYPE_ROUTE) && (route!=NULL)) { - route->interval=interval; - return TRP_SUCCESS; - } else + if (data==NULL) + return TRP_ERROR; + + switch (rec->type) { + case TRP_INFOREC_TYPE_ROUTE: + rec->data.route=talloc_get_type(data, TRP_INFOREC_ROUTE); + break; + default: return TRP_BADTYPE; + } + return TRP_SUCCESS; } /* generic record type */ -static void *trp_msg_info_rec_new(TALLOC_CTX *mem_ctx, TRP_MSG_INFO_TYPE type) +TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type) { - TRP_MSG_INFO_REC *new_rec=talloc(mem_ctx, TRP_MSG_INFO_REC); - struct trp_msg_info_type_entry *dtype=get_trp_msg_info_type_entry(type); + TRP_INFOREC *new_rec=talloc(mem_ctx, TRP_INFOREC); + struct trp_inforec_type_entry *dtype=get_trp_inforec_type_entry(type); - if ((new_rec != NULL) && (dtype->type != TRP_MSG_INFO_TYPE_UNKNOWN)) { + if ((new_rec != NULL) && (dtype->type != TRP_INFOREC_TYPE_UNKNOWN)) { new_rec->next=NULL; new_rec->type=type; - if (dtype->allocate!=NULL) - new_rec->data=dtype->allocate(new_rec); - if (new_rec->data==NULL) { - /* dtype->allocate() failed or did not exist */ - talloc_free(new_rec); new_rec=NULL; + if (dtype->allocate!=NULL) { + if (TRP_SUCCESS!=trp_inforec_set_data(new_rec, dtype->allocate(new_rec))) { + talloc_free(new_rec); + new_rec=NULL; + } } } return new_rec; } -/* parse a single record */ -static TRP_RC trp_parse_update_record(TALLOC_CTX *mem_ctx, TRP_MSG_INFO_REC **rec, json_t *jrecord) +void trp_inforec_free(TRP_INFOREC *rec) { - TALLOC_CTX *tmp_ctx=talloc_new(NULL); - TRP_MSG_INFO_TYPE rectype; - TRP_RC rc=TRP_ERROR; - char *s=NULL; - int num=0; - - rc=trp_get_json_string(jrecord, "record_type", &s, tmp_ctx); - if (rc != TRP_SUCCESS) - goto cleanup; - rectype=trp_msg_info_type_from_string(s); - talloc_free(s); s=NULL; - - (*rec)=trp_msg_info_rec_new(tmp_ctx, rectype); - if ((*rec)==NULL) { - rc=TRP_NOMEM; - goto cleanup; - } - - /* We only support route_info records for now*/ - if ((*rec)->type!=TRP_MSG_INFO_TYPE_ROUTE) { - rc=TRP_UNSUPPORTED; - goto cleanup; - } - - tr_debug("trp_parse_update_record: '%s' record found.", trp_msg_info_type_to_string((*rec)->type)); - - rc=trp_get_json_string(jrecord, "community", &s, tmp_ctx); - if (rc != TRP_SUCCESS) - goto cleanup; - if (TRP_SUCCESS!=trp_msg_info_route_set_comm(*rec, tr_new_name(s))) /* assumes route_info */ - goto cleanup; - talloc_free(s); s=NULL; - - rc=trp_get_json_string(jrecord, "realm", &s, tmp_ctx); - if (rc != TRP_SUCCESS) - goto cleanup; - if (TRP_SUCCESS!=trp_msg_info_route_set_realm(*rec, tr_new_name(s))) /* assumes route_info */ - goto cleanup; - talloc_free(s); s=NULL; - - rc=trp_get_json_string(jrecord, "trust_router", &s, tmp_ctx); - if (rc != TRP_SUCCESS) - goto cleanup; - if (TRP_SUCCESS!=trp_msg_info_route_set_trust_router(*rec, tr_new_name(s))) /* assumes route_info */ - goto cleanup; - talloc_free(s); s=NULL; - - rc=trp_get_json_integer(jrecord, "metric", &num); - if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_msg_info_route_set_metric(*rec,num))) - goto cleanup; - - rc=trp_get_json_integer(jrecord, "interval", &num); - if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_msg_info_route_set_interval(*rec,num))) - goto cleanup; - - talloc_steal(mem_ctx, *rec); - rc=TRP_SUCCESS; - -cleanup: - if (rc != TRP_SUCCESS) { - /* kind of a hack, assumes we only have route_info records */ - trp_msg_info_route_destructor((*rec)->data); - (*rec)=NULL; - } - talloc_free(tmp_ctx); - return rc; + if (rec!=NULL) + talloc_free(rec); } -static void *trp_route_update_new(TALLOC_CTX *mem_ctx) +TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx) { - TRP_ROUTE_UPDATE *new_body=talloc(mem_ctx, TRP_ROUTE_UPDATE); + TRP_UPD *new_body=talloc(mem_ctx, TRP_UPD); if (new_body!=NULL) { new_body->records=NULL; } + return new_body; } -/* Parse an update body. Creates a linked list of records in the msg->body talloc context. - * - * An error will be returned if any unparseable records are encountered. - * - * TODO: clean up return codes. - * TODO: should take a body, not a msg */ -static TRP_RC trp_parse_route_update(TRP_MSG *msg, json_t *jbody) +void trp_upd_free(TRP_UPD *update) { - TALLOC_CTX *tmp_ctx=talloc_new(NULL); - json_t *jrecords=NULL; - size_t ii=0; - size_t nrec=0; - TRP_ROUTE_UPDATE *msg_body=NULL; - TRP_MSG_INFO_REC *new_rec=NULL; - TRP_MSG_INFO_REC *list_tail=NULL; - TRP_RC rc=TRP_ERROR; - - if (msg->type != TRP_MSG_TYPE_UPDATE) { - rc=TRP_BADTYPE; - goto cleanup; - } - msg_body=talloc_get_type(msg->body, TRP_ROUTE_UPDATE); - if (msg_body==NULL) { - rc=TRP_BADTYPE; - goto cleanup; - } - - jrecords=json_object_get(jbody, "records"); - if ((jrecords==NULL) || (!json_is_array(jrecords))) { - rc=TRP_NOPARSE; - goto cleanup; - } - - tr_debug("trp_parse_route_update: found %d records", json_array_size(jrecords)); - /* process the array */ - for (ii=0; iirecords=new_rec; /* first is a special case */ - else - list_tail->next=new_rec; - - list_tail=new_rec; - } - - /* Succeeded. Move all of our new allocations into the correct talloc context */ - for (list_tail=msg_body->records; list_tail != NULL; list_tail=list_tail->next) - talloc_steal(msg->body, list_tail); /* all successfully parsed bodies belong to msg context */ - - rc=TRP_SUCCESS; - -cleanup: - talloc_free(tmp_ctx); - if ((rc != TRP_SUCCESS) && (msg_body != NULL)) - msg_body->records=NULL; /* don't leave this hanging */ - - return rc; + if (update!=NULL) + talloc_free(update); } + /* pretty print */ -static void trp_msg_info_route_print(void *rec_in) +static void trp_inforec_route_print(TRP_INFOREC_DATA data) { - TRP_MSG_INFO_ROUTE *rec=talloc_get_type(rec_in, TRP_MSG_INFO_ROUTE); /* null if wrong type */ - - if (rec!=NULL) { + if (data.route!=NULL) { printf(" community=%.*s\n realm=%.*s\n trust_router=%.*s\n metric=%d\n interval=%d]\n", - rec->comm->len, rec->comm->buf, - rec->realm->len, rec->realm->buf, - rec->trust_router->len, rec->trust_router->buf, - rec->metric, rec->interval); + data.route->comm->len, data.route->comm->buf, + data.route->realm->len, data.route->realm->buf, + data.route->trust_router->len, data.route->trust_router->buf, + data.route->metric, data.route->interval); } } -static int trp_route_req_destructor(void *object) +static int trp_req_destructor(void *object) { - TRP_ROUTE_REQ *body=talloc_get_type_abort(object, TRP_ROUTE_REQ); + TRP_REQ *body=talloc_get_type_abort(object, TRP_REQ); /* clean up TR_NAME data, which are not managed by talloc */ if (body->comm != NULL) { tr_free_name(body->comm); body->comm=NULL; - tr_debug("trp_route_req_destructor: freed community"); + tr_debug("trp_req_destructor: freed community"); } if (body->realm != NULL) { tr_free_name(body->realm); body->realm=NULL; - tr_debug("trp_route_req_destructor: freed realm"); + tr_debug("trp_req_destructor: freed realm"); } return 0; } -void *trp_route_req_new(TALLOC_CTX *mem_ctx) +TRP_REQ *trp_req_new(TALLOC_CTX *mem_ctx) { - TRP_ROUTE_REQ *new_body=talloc(mem_ctx, TRP_ROUTE_REQ); + TRP_REQ *new_body=talloc(mem_ctx, TRP_REQ); if (new_body != NULL) { new_body->comm=NULL; new_body->realm=NULL; } - talloc_set_destructor((void *)new_body, trp_route_req_destructor); + talloc_set_destructor((void *)new_body, trp_req_destructor); return new_body; } -void trp_route_req_set_comm(TRP_ROUTE_REQ *req, TR_NAME *comm) +void trp_req_free(TRP_REQ *req) { - req->comm=comm; + if (req!=NULL) + talloc_free(req); } -void trp_route_req_set_realm(TRP_ROUTE_REQ *req, TR_NAME *realm) -{ - req->realm=realm; -} - -/* TODO: clean up return codes. - * TODO: should take a body, not a msg */ -static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jbody) -{ - TALLOC_CTX *tmp_ctx=talloc_new(NULL); - TRP_ROUTE_REQ *msg_body=NULL; - char *s=NULL; - TRP_RC rc=TRP_ERROR; - - /* check message type and body type for agreement */ - if (msg->type != TRP_MSG_TYPE_ROUTE_REQ) { - rc=TRP_BADTYPE; - goto cleanup; - } - msg_body=talloc_get_type(msg->body, TRP_ROUTE_REQ); - if (msg_body==NULL) { - rc=TRP_BADTYPE; - goto cleanup; - } - - rc=trp_get_json_string(jbody, "community", &s, tmp_ctx); - if (rc!=TRP_SUCCESS) - goto cleanup; - msg_body->comm=tr_new_name(s); - talloc_free(s); s=NULL; - - rc=trp_get_json_string(jbody, "realm", &s, tmp_ctx); - if (rc!=TRP_SUCCESS) - goto cleanup; - msg_body->realm=tr_new_name(s); - talloc_free(s); s=NULL; - - rc=TRP_SUCCESS; -cleanup: - talloc_free(tmp_ctx); - return rc; -} - -static json_t *trp_encode_body(TRP_MSG_TYPE type, void *body) -{ - struct trp_msg_type_entry *msgtype=get_trp_msg_type_entry(type); - - if ((msgtype->type==TRP_MSG_TYPE_UNKNOWN) || (msgtype->encode==NULL)) - return NULL; - - return msgtype->encode(body); -} - -char *trp_encode_msg(TRP_MSG *msg) -{ - json_t *jmsg=NULL; - json_t *jtype=NULL; - json_t *jbody=NULL; - char *encoded=NULL; - - jbody=trp_encode_body(msg->type, msg->body); - if (jbody!=NULL) { - jmsg=json_object(); - if (jmsg==NULL) { - /* failed */ - json_decref(jbody); - } else { - jtype=json_string(trp_msg_type_to_string(msg->type)); - if (jtype==NULL) { - json_decref(jbody); - } else { - json_object_set_new(jmsg, "message_type", jtype); - json_object_set_new(jmsg, "body", jbody); - encoded=json_dumps(jmsg, 0); - } - json_decref(jmsg); - } - } - return encoded; -} - -/* add record data to jrec */ -static TRP_RC trp_encode_info_route(json_t *jrec, void *route_in) -{ - TRP_MSG_INFO_ROUTE *route=talloc_get_type(route_in, TRP_MSG_INFO_ROUTE); - json_t *jstr=NULL; - json_t *jint=NULL; - char *s=NULL; - - if (route==NULL) - return TRP_BADTYPE; - - s=tr_name_strdup(route->comm); - if (s==NULL) - return TRP_NOMEM; - jstr=json_string(s); - free(s);s=NULL; - if(jstr==NULL) - return TRP_ERROR; - json_object_set_new(jrec, "community", jstr); - - s=tr_name_strdup(route->realm); - if (s==NULL) - return TRP_NOMEM; - jstr=json_string(s); - free(s);s=NULL; - if(jstr==NULL) - return TRP_ERROR; - json_object_set_new(jrec, "realm", jstr); - - s=tr_name_strdup(route->trust_router); - if (s==NULL) - return TRP_NOMEM; - jstr=json_string(s); - free(s);s=NULL; - if(jstr==NULL) - return TRP_ERROR; - json_object_set_new(jrec, "trust_router", jstr); - - jint=json_integer(route->metric); - if(jint==NULL) - return TRP_ERROR; - json_object_set_new(jrec, "metric", jint); - - jint=json_integer(route->interval); - if(jint==NULL) - return TRP_ERROR; - json_object_set_new(jrec, "interval", jint); - - return TRP_SUCCESS; -} - -static json_t *trp_encode_info_rec(TRP_MSG_INFO_REC *rec) -{ - struct trp_msg_info_type_entry *rectype=get_trp_msg_info_type_entry(rec->type); - json_t *jrec=NULL; - json_t *jstr=NULL; - - if (rectype->type==TRP_MSG_INFO_TYPE_UNKNOWN) - return NULL; - - jrec=json_object(); - if (jrec==NULL) - return NULL; - - jstr=json_string(trp_msg_info_type_to_string(rec->type)); - if (jstr==NULL) { - json_decref(jrec); - return NULL; - } - json_object_set_new(jrec, "record_type", jstr); - - if ((rectype->encode==NULL) || (TRP_SUCCESS!=rectype->encode(jrec, rec->data))) { - json_decref(jrec); - return NULL; - } - - return jrec; -} - -static json_t *trp_encode_route_update(void *update_in) -{ - TRP_ROUTE_UPDATE *update=talloc_get_type(update_in, TRP_ROUTE_UPDATE); /* null if wrong type */ - json_t *jbody=NULL; - json_t *jrecords=NULL; - json_t *jrec=NULL; - TRP_MSG_INFO_REC *rec; - - if (update==NULL) - return NULL; - - jbody=json_object(); - if (jbody==NULL) - return NULL; - - jrecords=json_array(); - if (jrecords==NULL) { - json_decref(jbody); - return NULL; - } - json_object_set_new(jbody, "records", jrecords); /* jrecords now a "borrowed" reference */ - for (rec=update->records; rec!=NULL; rec=rec->next) { - jrec=trp_encode_info_rec(rec); - if (jrec==NULL) { - json_decref(jbody); /* also decs jrecords and any elements */ - return NULL; - } - if (0!=json_array_append_new(jrecords, jrec)) { - json_decref(jbody); /* also decs jrecords and any elements */ - json_decref(jrec); /* this one did not get added so dec explicitly */ - return NULL; - } - } - - return jbody; -} - -static json_t *trp_encode_route_req(void *req_in) -{ - TRP_ROUTE_REQ *req=talloc_get_type(req_in, TRP_ROUTE_REQ); /* null if wrong type */ - json_t *jbody=NULL; - json_t *jstr=NULL; - char *s=NULL; - - if (req==NULL) - return NULL; - - jbody=json_object(); - if (jbody==NULL) - return NULL; - - s=tr_name_strdup(req->comm); /* ensures null termination */ - if (s==NULL) { - json_decref(jbody); - return NULL; - } - jstr=json_string(s); - free(s); s=NULL; - if (jstr==NULL) { - json_decref(jbody); - return NULL; - } - json_object_set_new(jbody, "community", jstr); - - s=tr_name_strdup(req->realm); /* ensures null termination */ - if (s==NULL) { - json_decref(jbody); - return NULL; - } - jstr=json_string(s); - free(s); s=NULL; - if (jstr==NULL) { - json_decref(jbody); - return NULL; - } - json_object_set_new(jbody, "realm", jstr); - - return jbody; -} - -static void trp_msg_info_rec_print(TRP_MSG_INFO_REC *rec) -{ - struct trp_msg_info_type_entry *rectype=get_trp_msg_info_type_entry(rec->type); - - if (rectype->print != NULL) { - printf(" [record_type=%s\n", trp_msg_info_type_to_string(rec->type)); - rectype->print(rec->data); - } - else - printf(" [record_type=%s, (no print method)]\n"); -} - -static void trp_route_update_print(void *body_in) -{ - TRP_ROUTE_UPDATE *body=talloc_get_type(body_in, TRP_ROUTE_UPDATE); /* null if wrong type */ - TRP_MSG_INFO_REC *rec=NULL; - - if (body!=NULL) { - printf(" {records=\n"); - for (rec=body->records; rec!=NULL; rec=rec->next) - trp_msg_info_rec_print(rec); - printf(" }\n"); - } -} - -static void trp_route_req_print(void *body_in) -{ - TRP_ROUTE_REQ *body=talloc_get_type(body_in, TRP_ROUTE_REQ); /* null if wrong type */ - - if (body!=NULL) { - printf(" {community=%.*s\n realm=%.*s}\n", - body->comm->len, body->comm->buf, - body->realm->len, body->realm->buf); - } -} - -static void trp_msg_body_print(void *body, TRP_MSG_TYPE msgtype) -{ - struct trp_msg_type_entry *info=get_trp_msg_type_entry(msgtype); - info->print(body); -} - -void trp_msg_print(TRP_MSG *msg) -{ - /* right now just assumes update */ - printf("{message_type=%s\n", trp_msg_type_to_string(msg->type)); - trp_msg_body_print(msg->body, msg->type); - printf("}\n"); -} - -/* returns a pointer to one of the message body types, or NULL on error/unknown type */ -static void *trp_msg_body_new(TALLOC_CTX *mem_ctx, TRP_MSG_TYPE msgtype) -{ - void *new_body=NULL; - struct trp_msg_type_entry *info=get_trp_msg_type_entry(msgtype); - - if (info->type==TRP_MSG_TYPE_UNKNOWN) { - tr_debug("trp_msg_body_new: Unknown type %d.", info->type); - return NULL; - } - - new_body=info->allocate(mem_ctx); - msg_body_type_check(msgtype, new_body); /* aborts program on type violation */ - return new_body; -} - -/* call the correct parser */ -static TRP_RC trp_parse_msg_body(TRP_MSG *msg, json_t *jbody) -{ - struct trp_msg_type_entry *info=get_trp_msg_type_entry(msg->type); - - if (info->type==TRP_MSG_TYPE_UNKNOWN) { - tr_debug("trp_msg_body_parse: Unknown type %d.", info->type); - return TRP_ERROR; - } - - return info->parse(msg, jbody); -} - - -TRP_RC trp_parse_msg(TALLOC_CTX *mem_ctx, const char *buf, size_t buflen, TRP_MSG **msg) -{ - TALLOC_CTX *tmp_ctx=talloc_new(NULL); - TRP_MSG *new_msg=NULL; - TRP_RC msg_rc=TRP_ERROR; - json_error_t json_err; - json_t *jmsg=NULL; /* handle for the whole msg */ - json_t *jbody=NULL; - char *s; - - tr_debug("trp_parse_msg: parsing %d bytes", buflen); - - jmsg=json_loadb(buf, buflen, 0, &json_err); - if (jmsg == NULL) { - tr_debug("trp_parse_msg: Error parsing message."); - msg_rc=TRP_NOPARSE; - goto cleanup; - } - - /* parse the common part of the message */ - new_msg=trp_msg_new(tmp_ctx); - if (new_msg == NULL) { - tr_debug("trp_parse_msg: Error allocating message."); - msg_rc=TRP_NOMEM; - goto cleanup; - } - - switch (trp_get_json_string(jmsg, "message_type", &s, new_msg)) { - case TRP_SUCCESS: - break; - case TRP_NOPARSE: - tr_debug("trp_parse_msg: required attribute 'message_type' not present."); - msg_rc=TRP_NOPARSE; - goto cleanup; - case TRP_BADTYPE: - tr_debug("trp_parse_msg: required attribute 'message_type' is not a string."); - msg_rc=TRP_NOPARSE; - goto cleanup; - default: - tr_debug("trp_parse_msg: error parsing 'message_type'."); - msg_rc=TRP_NOPARSE; - goto cleanup; - } - - tr_debug("trp_parse_msg: 'message_type' is '%s'", s); - new_msg->type = trp_msg_type_from_string(s); - if (new_msg->type==TRP_MSG_TYPE_UNKNOWN) { - tr_debug("trp_parse_msg: Parsing error, unknown message_type (%s).", s); - msg_rc=TRP_NOPARSE; - goto cleanup; - } - - new_msg->body=trp_msg_body_new(new_msg, new_msg->type); - if (new_msg->body==NULL) { - tr_debug("trp_parse_msg: Error allocating message body for message_type %d.", new_msg->type); - msg_rc=TRP_NOMEM; - goto cleanup; - } - jbody=json_object_get(jmsg, "body"); - if (jbody==NULL) { - tr_debug("trp_parse_msg: Message body not found."); - msg_rc=TRP_NOPARSE; - goto cleanup; - } - - switch (trp_parse_msg_body(new_msg, jbody)) { - case TRP_SUCCESS: - break; - default: - tr_debug("trp_parse_msg: Error parsing message body."); - goto cleanup; - } - - /* success! */ - (*msg)=new_msg; - new_msg=NULL; - talloc_steal(mem_ctx, *msg); - msg_rc=TRP_SUCCESS; - -cleanup: - talloc_free(tmp_ctx); - json_decref(jmsg); - return msg_rc; -} -- 2.1.4