From add2ac18ca50d11a28a40d50a989ecb936b9493e Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Wed, 20 Jul 2016 00:02:27 -0400 Subject: [PATCH] Connect to hard-coded peer and exchange route info. Buggy and incomplete. --- common/tr_config.c | 33 +++++++++-- common/tr_msg.c | 1 + include/tr_config.h | 9 ++- include/tr_trp.h | 4 +- include/trp_internal.h | 9 ++- include/trp_ptable.h | 6 +- include/trp_rtable.h | 5 ++ include/trust_router/trp.h | 5 ++ tr/tr_cfgwatch.c | 10 ++-- tr/tr_main.c | 28 ++++----- tr/tr_trp.c | 140 ++++++++++++++++++++++++++++++++++++++++----- trp/trp_conn.c | 5 +- trp/trp_ptable.c | 22 +++++-- trp/trp_rtable.c | 25 ++++++++ trp/trp_upd.c | 23 +++++++- trp/trpc.c | 22 ++++++- trp/trps.c | 105 ++++++++++++++++++++-------------- 17 files changed, 359 insertions(+), 93 deletions(-) diff --git a/common/tr_config.c b/common/tr_config.c index 6a3d4dc..4d05d4b 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -98,6 +98,7 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) { json_t *jcfgsettle = NULL; json_t *jroutesweep = NULL; json_t *jrouteupdate = NULL; + json_t *jrouteconnect = NULL; if ((!trc) || (!jcfg)) return TR_CFG_BAD_PARAMS; @@ -165,21 +166,41 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) { return TR_CFG_NOPARSE; } } - if (NULL != (jroutesweep = json_object_get(jint, "route_sweep_interval"))) { + + if (NULL != (jrouteconnect = json_object_get(jint, "trp_connect_interval"))) { + if (json_is_number(jrouteconnect)) { + trc->internal->trp_connect_interval = json_integer_value(jrouteconnect); + } else { + tr_debug("tr_cfg_parse_internal: Parsing error, trp_connect_interval is not a number."); + return TR_CFG_NOPARSE; + } + } else { + /* if not configured, use the default */ + trc->internal->trp_connect_interval=TR_DEFAULT_TRP_CONNECT_INTERVAL; + } + + if (NULL != (jroutesweep = json_object_get(jint, "trp_sweep_interval"))) { if (json_is_number(jroutesweep)) { - trc->internal->route_sweep_interval = json_integer_value(jroutesweep); + trc->internal->trp_sweep_interval = json_integer_value(jroutesweep); } else { - tr_debug("tr_cfg_parse_internal: Parsing error, route_sweep_interval is not a number."); + tr_debug("tr_cfg_parse_internal: Parsing error, trp_sweep_interval is not a number."); return TR_CFG_NOPARSE; } + } else { + /* if not configured, use the default */ + trc->internal->trp_sweep_interval=TR_DEFAULT_TRP_SWEEP_INTERVAL; } - if (NULL != (jrouteupdate = json_object_get(jint, "route_update_interval"))) { + + if (NULL != (jrouteupdate = json_object_get(jint, "trp_update_interval"))) { if (json_is_number(jrouteupdate)) { - trc->internal->route_update_interval = json_integer_value(jrouteupdate); + trc->internal->trp_update_interval = json_integer_value(jrouteupdate); } else { - tr_debug("tr_cfg_parse_internal: Parsing error, route_update_interval is not a number."); + tr_debug("tr_cfg_parse_internal: Parsing error, trp_update_interval is not a number."); return TR_CFG_NOPARSE; } + } else { + /* if not configured, use the default */ + trc->internal->trp_update_interval=TR_DEFAULT_TRP_UPDATE_INTERVAL; } if (NULL != (jlog = json_object_get(jint, "logging"))) { diff --git a/common/tr_msg.c b/common/tr_msg.c index 6295068..b2964b6 100644 --- a/common/tr_msg.c +++ b/common/tr_msg.c @@ -717,6 +717,7 @@ static json_t *tr_msg_encode_trp_upd(TRP_UPD *update) } json_object_set_new(jupdate, "records", jrecords); /* jrecords now a "borrowed" reference */ for (rec=trp_upd_get_inforec(update); rec!=NULL; rec=trp_inforec_get_next(rec)) { + tr_debug("tr_msg_encode_trp_upd: encoding inforec."); jrec=tr_msg_encode_inforec(rec); if (jrec==NULL) { json_decref(jupdate); /* also decs jrecords and any elements */ diff --git a/include/tr_config.h b/include/tr_config.h index 6cffb00..626b20b 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -52,7 +52,9 @@ #define TR_DEFAULT_TRPS_PORT 12310 #define TR_DEFAULT_LOG_THRESHOLD LOG_INFO #define TR_DEFAULT_CONSOLE_THRESHOLD LOG_NOTICE - +#define TR_DEFAULT_TRP_CONNECT_INTERVAL 10 +#define TR_DEFAULT_TRP_UPDATE_INTERVAL 120 +#define TR_DEFAULT_TRP_SWEEP_INTERVAL 30 typedef enum tr_cfg_rc { TR_CFG_SUCCESS = 0, /* No error */ TR_CFG_ERROR, /* General processing error */ @@ -70,8 +72,9 @@ typedef struct tr_cfg_internal { int console_threshold; unsigned int cfg_poll_interval; unsigned int cfg_settle_count; - unsigned int route_sweep_interval; - unsigned int route_update_interval; + unsigned int trp_sweep_interval; + unsigned int trp_update_interval; + unsigned int trp_connect_interval; } TR_CFG_INTERNAL; typedef struct tr_cfg { diff --git a/include/tr_trp.h b/include/tr_trp.h index 53033f6..87f4ce0 100644 --- a/include/tr_trp.h +++ b/include/tr_trp.h @@ -12,6 +12,7 @@ typedef struct tr_trps_events { struct tr_socket_event *listen_ev; struct event *mq_ev; + struct event *connect_ev; struct event *update_ev; struct event *sweep_ev; } TR_TRPS_EVENTS; @@ -20,6 +21,7 @@ typedef struct tr_trps_events { TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx); TRP_RC tr_trps_event_init(struct event_base *base, TRPS_INSTANCE *trps, TR_CFG_MGR *cfg_mgr, TR_TRPS_EVENTS *trps_ev); -TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, const char *server, unsigned int port); +TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer); void tr_config_changed(TR_CFG *new_cfg, void *cookie); +TRP_RC tr_connect_to_peers(TRPS_INSTANCE *trps); #endif /* TR_TRP_H */ diff --git a/include/trp_internal.h b/include/trp_internal.h index 5151075..20e54b8 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -76,6 +76,7 @@ typedef client_cb_fn TRP_AUTH_FUNC; typedef struct trpc_instance TRPC_INSTANCE; struct trpc_instance { TRPC_INSTANCE *next; + TR_NAME *gssname; char *server; unsigned int port; TRP_CONNECTION *conn; @@ -95,6 +96,7 @@ struct trps_instance { TR_MQ *mq; /* incoming message queue */ TRP_PTABLE *ptable; /* peer table */ TRP_RTABLE *rtable; /* route table */ + struct timeval connect_interval; /* interval between connection refreshes */ struct timeval update_interval; /* interval between scheduled updates */ struct timeval sweep_interval; /* interval between route table sweeps */ }; @@ -132,6 +134,8 @@ TRPC_INSTANCE *trpc_remove(TRPC_INSTANCE *trpc, TRPC_INSTANCE *remove); void trpc_append(TRPC_INSTANCE *trpc, TRPC_INSTANCE *new); char *trpc_get_server(TRPC_INSTANCE *trpc); void trpc_set_server(TRPC_INSTANCE *trpc, char *server); +TR_NAME *trpc_get_gssname(TRPC_INSTANCE *trpc); +void trpc_set_gssname(TRPC_INSTANCE *trpc, TR_NAME *gssname); unsigned int trpc_get_port(TRPC_INSTANCE *trpc); void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port); DH *trpc_get_dh(TRPC_INSTANCE *trpc); @@ -148,11 +152,14 @@ 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_connect_interval(TRPS_INSTANCE *trps, unsigned int interval); +unsigned int trps_get_connect_interval(TRPS_INSTANCE *trps); void trps_set_update_interval(TRPS_INSTANCE *trps, unsigned int interval); unsigned int trps_get_update_interval(TRPS_INSTANCE *trps); void trps_set_sweep_interval(TRPS_INSTANCE *trps, unsigned int interval); unsigned int trps_get_sweep_interval(TRPS_INSTANCE *trps); -TRP_RC trps_send_msg (TRPS_INSTANCE *trps, TR_NAME *peer_gssname, const char *msg); +TRPC_INSTANCE *trps_find_trpc(TRPS_INSTANCE *trps, TRP_PEER *peer); +TRP_RC trps_send_msg (TRPS_INSTANCE *trps, TRP_PEER *peer, const char *msg); void trps_add_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *new); void trps_remove_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *remove); void trps_add_trpc(TRPS_INSTANCE *trps, TRPC_INSTANCE *trpc); diff --git a/include/trp_ptable.h b/include/trp_ptable.h index 23d729d..ec14824 100644 --- a/include/trp_ptable.h +++ b/include/trp_ptable.h @@ -1,6 +1,7 @@ #ifndef _TRP_PTABLE_H_ #define _TRP_PTABLE_H_ +#include #include #include @@ -8,10 +9,11 @@ typedef struct trp_peer TRP_PEER; struct trp_peer { + TRP_PEER *next; /* for making a linked list */ char *server; unsigned int port; unsigned int linkcost; - TRP_PEER *next; /* for making a linked list */ + struct timespec last_conn_attempt; }; typedef struct trp_ptable { @@ -41,6 +43,8 @@ TR_NAME *trp_peer_get_gssname(TRP_PEER *peer); unsigned int trp_peer_get_port(TRP_PEER *peer); void trp_peer_set_port(TRP_PEER *peer, unsigned int port); unsigned int trp_peer_get_linkcost(TRP_PEER *peer); +struct timespec *trp_peer_get_last_conn_attempt(TRP_PEER *peer); +void trp_peer_set_last_conn_attempt(TRP_PEER *peer, struct timespec *time); void trp_peer_set_linkcost(TRP_PEER *peer, unsigned int linkcost); char *trp_peer_to_str(TALLOC_CTX *memctx, TRP_PEER *peer, const char *sep); diff --git a/include/trp_rtable.h b/include/trp_rtable.h index 2cf60e3..e9ebd6f 100644 --- a/include/trp_rtable.h +++ b/include/trp_rtable.h @@ -42,16 +42,21 @@ TRP_RENTRY *trp_rentry_new(TALLOC_CTX *mem_ctx); void trp_rentry_free(TRP_RENTRY *entry); void trp_rentry_set_apc(TRP_RENTRY *entry, TR_NAME *apc); TR_NAME *trp_rentry_get_apc(TRP_RENTRY *entry); +TR_NAME *trp_rentry_dup_apc(TRP_RENTRY *entry); void trp_rentry_set_realm(TRP_RENTRY *entry, TR_NAME *realm); TR_NAME *trp_rentry_get_realm(TRP_RENTRY *entry); +TR_NAME *trp_rentry_dup_realm(TRP_RENTRY *entry); void trp_rentry_set_trust_router(TRP_RENTRY *entry, TR_NAME *tr); TR_NAME *trp_rentry_get_trust_router(TRP_RENTRY *entry); +TR_NAME *trp_rentry_dup_trust_router(TRP_RENTRY *entry); void trp_rentry_set_peer(TRP_RENTRY *entry, TR_NAME *peer); TR_NAME *trp_rentry_get_peer(TRP_RENTRY *entry); +TR_NAME *trp_rentry_dup_peer(TRP_RENTRY *entry); void trp_rentry_set_metric(TRP_RENTRY *entry, unsigned int metric); unsigned int trp_rentry_get_metric(TRP_RENTRY *entry); void trp_rentry_set_next_hop(TRP_RENTRY *entry, TR_NAME *next_hop); TR_NAME *trp_rentry_get_next_hop(TRP_RENTRY *entry); +TR_NAME *trp_rentry_dup_next_hop(TRP_RENTRY *entry); void trp_rentry_set_selected(TRP_RENTRY *entry, int sel); int trp_rentry_get_selected(TRP_RENTRY *entry); void trp_rentry_set_interval(TRP_RENTRY *entry, int interval); diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h index a267fd1..f1032a2 100644 --- a/include/trust_router/trp.h +++ b/include/trust_router/trp.h @@ -20,6 +20,7 @@ typedef enum trp_rc { TRP_BADTYPE, /* typing error */ TRP_UNSUPPORTED, /* unsupported feature */ TRP_BADARG, /* bad argument */ + TRP_CLOCKERR, /* error reading time */ } TRP_RC; typedef enum trp_inforec_type { @@ -48,12 +49,16 @@ void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec); TR_EXPORT TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec); void trp_inforec_set_type(TRP_INFOREC *rec, TRP_INFOREC_TYPE type); TR_EXPORT TR_NAME *trp_inforec_get_comm(TRP_INFOREC *rec); +TR_EXPORT TR_NAME *trp_inforec_dup_comm(TRP_INFOREC *rec); TRP_RC trp_inforec_set_comm(TRP_INFOREC *rec, TR_NAME *comm); TR_EXPORT TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec); +TR_EXPORT TR_NAME *trp_inforec_dup_realm(TRP_INFOREC *rec); TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm); TR_EXPORT TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec); +TR_EXPORT TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec); TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router); TR_EXPORT TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec); +TR_EXPORT TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec); TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop); TR_EXPORT unsigned int trp_inforec_get_metric(TRP_INFOREC *rec); TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric); diff --git a/tr/tr_cfgwatch.c b/tr/tr_cfgwatch.c index ff5eb77..e6ec7ec 100644 --- a/tr/tr_cfgwatch.c +++ b/tr/tr_cfgwatch.c @@ -195,6 +195,11 @@ int tr_read_and_apply_config(TR_CFGWATCH *cfgwatch) retval=1; goto cleanup; } + /* call callback to notify system of new configuration */ + tr_debug("tr_read_and_apply_config: calling update callback function."); + if (cfgwatch->update_cb!=NULL) + cfgwatch->update_cb(cfgwatch->cfg_mgr->active, cfgwatch->update_cookie); + /* give ownership of the new_fstat_list to caller's context */ if (cfgwatch->fstat_list != NULL) { /* free the old one */ @@ -236,11 +241,8 @@ static void tr_cfgwatch_event_cb(int listener, short event, void *arg) tr_notice("Configuration file change settled, attempting to update configuration."); if (0 != tr_read_and_apply_config(cfg_status)) tr_warning("Configuration file update failed. Using previous configuration."); - else { - if (cfg_status->update_cb!=NULL) - cfg_status->update_cb(cfg_status->cfg_mgr->active, cfg_status->update_cookie); + else tr_notice("Configuration updated successfully."); - } cfg_status->change_detected=0; } } diff --git a/tr/tr_main.c b/tr/tr_main.c index 411ee04..2df7ff5 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -211,6 +211,18 @@ int main(int argc, char *argv[]) return 1; } + /***** initialize the trust path query server instance *****/ + if (NULL == (tr->tids = tids_create (tr))) { + tr_crit("Error initializing Trust Path Query Server instance."); + return 1; + } + + /***** initialize the trust router protocol server instance *****/ + if (NULL == (tr->trps = trps_new(tr))) { + tr_crit("Error initializing Trust Router Protocol Server instance."); + return 1; + } + /***** process configuration *****/ tr->cfgwatch=tr_cfgwatch_create(tr); if (tr->cfgwatch == NULL) { @@ -219,24 +231,12 @@ int main(int argc, char *argv[]) } tr->cfgwatch->config_dir=opts.config_dir; tr->cfgwatch->cfg_mgr=tr->cfg_mgr; + tr->cfgwatch->update_cb=tr_config_changed; /* handle configuration changes */ + tr->cfgwatch->update_cookie=(void *)(tr->trps); if (0 != tr_read_and_apply_config(tr->cfgwatch)) { tr_crit("Error reading configuration, exiting."); return 1; } - tr->cfgwatch->update_cb=tr_config_changed; /* handle configuration changes */ - tr->cfgwatch->update_cookie=(void *)tr; - - /***** initialize the trust path query server instance *****/ - if (NULL == (tr->tids = tids_create (tr))) { - tr_crit("Error initializing Trust Path Query Server instance."); - return 1; - } - - /***** initialize the trust router protocol server instance *****/ - if (NULL == (tr->trps = trps_new(tr))) { - tr_crit("Error initializing Trust Router Protocol Server instance."); - return 1; - } /***** Set up the event loop *****/ ev_base=tr_event_loop_init(); /* Set up the event loop */ diff --git a/tr/tr_trp.c b/tr/tr_trp.c index db66571..67a5c88 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -6,10 +6,13 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -149,11 +152,33 @@ static void tr_trps_event_cb(int listener, short event, void *arg) talloc_free(tmp_ctx); } -static void tr_trps_cleanup_thread(TRPS_INSTANCE *trps, TRP_CONNECTION *conn) +static void tr_trps_cleanup_conn(TRPS_INSTANCE *trps, TRP_CONNECTION *conn) { /* everything belonging to the thread is in the TRP_CONNECTION * associated with it */ trps_remove_connection(trps, conn); + trp_connection_free(conn); + tr_debug("Deleted connection"); +} + +#if 0 +static void tr_trpc_abort(TRPC_INSTANCE *trpc) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + TR_MQ_MSG *msg=tr_mq_msg_new(tmp_ctx, "trpc_abort"); + tr_mq_msg_set_payload(msg, (void *)conn, NULL); /* do not pass a free routine */ + trpc_mq_append(msg); /* gives msg over to the queue to manage */ + +} +#endif + +static void tr_trps_cleanup_trpc(TRPS_INSTANCE *trps, TRPC_INSTANCE *trpc) +{ + /* everything belonging to the thread is in the TRP_CONNECTION + * associated with it */ +/* tr_trpc_abort(trpc); */ /* tell trpc to abort */ + trps_remove_trpc(trps, trpc); + trpc_free(trpc); tr_debug("Deleted connection"); } @@ -178,10 +203,17 @@ static void tr_trps_process_mq(int socket, short event, void *arg) while (msg!=NULL) { s=tr_mq_msg_get_message(msg); if (0==strcmp(s, "trps_thread_exit")) { - tr_trps_cleanup_thread(trps, - talloc_get_type_abort(tr_mq_msg_get_payload(msg), - TRP_CONNECTION)); + tr_trps_cleanup_conn(trps, + talloc_get_type_abort(tr_mq_msg_get_payload(msg), + TRP_CONNECTION)); } + else if (0==strcmp(s, "trpc_thread_exit")) { + /* trpc connection died */ + tr_trps_cleanup_trpc(trps, + talloc_get_type_abort(tr_mq_msg_get_payload(msg), + TRPC_INSTANCE)); + } + else if (0==strcmp(s, "tr_msg")) { if (trps_handle_tr_msg(trps, tr_mq_msg_get_payload(msg))!=TRP_SUCCESS) tr_notice("tr_trps_process_mq: error handling message."); @@ -214,17 +246,33 @@ static void tr_trps_sweep(int listener, short event, void *arg) TRPS_INSTANCE *trps=cookie->trps; struct event *ev=cookie->ev; - tr_debug("tr_trps_sweep: sweeping routes"); + tr_debug("tr_trps_sweep: sweeping routes."); trps_sweep_routes(trps); /* schedule the event to run again */ event_add(ev, &(trps->sweep_interval)); } +static void tr_connection_update(int listener, short event, void *arg) +{ + struct tr_trps_event_cookie *cookie=talloc_get_type_abort(arg, struct tr_trps_event_cookie); + TRPS_INSTANCE *trps=cookie->trps; + struct event *ev=cookie->ev; + + tr_debug("tr_connection_update: checking peer connections."); + tr_connect_to_peers(trps); + /* schedule the event to run again */ + event_add(ev, &(trps->connect_interval)); +} + static int tr_trps_events_destructor(void *obj) { TR_TRPS_EVENTS *ev=talloc_get_type_abort(obj, TR_TRPS_EVENTS); if (ev->mq_ev!=NULL) event_free(ev->mq_ev); + if (ev->connect_ev!=NULL) + event_free(ev->connect_ev); + if (ev->update_ev!=NULL) + event_free(ev->update_ev); if (ev->sweep_ev!=NULL) event_free(ev->sweep_ev); return 0; @@ -235,6 +283,7 @@ TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx) if (ev!=NULL) { ev->listen_ev=talloc(ev, struct tr_socket_event); ev->mq_ev=NULL; + ev->connect_ev=NULL; ev->update_ev=NULL; ev->sweep_ev=NULL; if (ev->listen_ev==NULL) { @@ -256,6 +305,7 @@ TRP_RC tr_trps_event_init(struct event_base *base, TALLOC_CTX *tmp_ctx=talloc_new(NULL); struct tr_socket_event *listen_ev=NULL; struct tr_trps_event_cookie *trps_cookie=NULL; + struct tr_trps_event_cookie *connection_cookie=NULL; struct tr_trps_event_cookie *update_cookie=NULL; struct tr_trps_event_cookie *sweep_cookie=NULL; TRP_RC retval=TRP_ERROR; @@ -312,6 +362,20 @@ TRP_RC tr_trps_event_init(struct event_base *base, (void *)trps); tr_mq_set_notify_cb(trps->mq, tr_trps_mq_cb, trps_ev->mq_ev); + /* now set up the peer connection timer event */ + connection_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + if (connection_cookie == NULL) { + tr_debug("tr_trps_event_init: Unable to allocate connection_cookie."); + retval=TRP_NOMEM; + goto cleanup; + } + connection_cookie->trps=trps; + connection_cookie->cfg_mgr=cfg_mgr; + talloc_steal(trps, connection_cookie); + trps_ev->connect_ev=event_new(base, -1, EV_TIMEOUT, tr_connection_update, (void *)connection_cookie); + connection_cookie->ev=trps_ev->connect_ev; /* in case it needs to frob the event */ + event_add(trps_ev->connect_ev, &(trps->connect_interval)); + /* now set up the route update timer event */ update_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); if (update_cookie == NULL) { @@ -451,7 +515,7 @@ static void *tr_trpc_thread(void *arg) } /* starts a trpc thread to connect to server:port */ -TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, const char *server, unsigned int port) +TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TRPC_INSTANCE *trpc=NULL; @@ -472,8 +536,9 @@ TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, const char *server, unsigne goto cleanup; } trpc_set_conn(trpc, conn); - trpc_set_server(trpc, talloc_strdup(trpc, server)); - trpc_set_port(trpc, port); + trpc_set_server(trpc, talloc_strdup(trpc, trp_peer_get_server(peer))); + trpc_set_port(trpc, trp_peer_get_port(peer)); + trpc_set_gssname(trpc, trp_peer_get_gssname(peer)); tr_debug("tr_trpc_initiate: allocated connection"); /* start thread */ @@ -491,19 +556,68 @@ TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, const char *server, unsigne tr_debug("tr_trpc_initiate: started trpc thread"); trps_add_trpc(trps, trpc); - talloc_report_full(trps, stderr); - talloc_report_full(tmp_ctx, stderr); - cleanup: talloc_free(tmp_ctx); return trpc; } +/* decide how often to attempt to connect to a peer */ +static int tr_conn_attempt_due(TRPS_INSTANCE *trps, TRP_PEER *peer, struct timespec *when) +{ + return 1; /* currently make an attempt every cycle */ +} + +/* open missing connections to peers */ +TRP_RC tr_connect_to_peers(TRPS_INSTANCE *trps) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + TRP_PTABLE_ITER *iter=trp_ptable_iter_new(tmp_ctx); + TRP_PEER *peer=NULL; + TRPC_INSTANCE *trpc=NULL; + struct timespec curtime={0,0}; + TRP_RC rc=TRP_ERROR; + + if (clock_gettime(CLOCK_REALTIME, &curtime)) { + tr_err("tr_connect_to_peers: failed to read time."); + rc=TRP_CLOCKERR; + goto cleanup; + } + + for (peer=trp_ptable_iter_first(iter, trps->ptable); + peer!=NULL; + peer=trp_ptable_iter_next(iter)) + { + if (trps_find_trpc(trps, peer)==NULL) { + tr_debug("tr_connect_to_peers: %.*s missing connection.", + trp_peer_get_gssname(peer)->len, trp_peer_get_gssname(peer)->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 */ + trpc=tr_trpc_initiate(trps, peer); + if (trpc==NULL) { + tr_err("tr_connect_to_peers: unable to initiate TRP connection to %s:%u.", + trp_peer_get_server(peer), + trp_peer_get_port(peer)); + } + } + } + } + rc=TRP_SUCCESS; + +cleanup: + trp_ptable_iter_free(iter); + talloc_free(tmp_ctx); + return rc; +} + + /* Called by the config manager after a change to the active configuration. * Updates configuration of objects that do not know about the config manager. */ void tr_config_changed(TR_CFG *new_cfg, void *cookie) { TRPS_INSTANCE *trps=talloc_get_type_abort(cookie, TRPS_INSTANCE); - trps_set_update_interval(trps, new_cfg->internal->route_update_interval); - trps_set_sweep_interval(trps, new_cfg->internal->route_sweep_interval); + 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); } + diff --git a/trp/trp_conn.c b/trp/trp_conn.c index 53b0a0d..dc3c961 100644 --- a/trp/trp_conn.c +++ b/trp/trp_conn.c @@ -224,6 +224,7 @@ TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx) trp_connection_set_gssname(new_conn, NULL); trp_connection_mutex_init(new_conn); trp_connection_set_status(new_conn, TRP_CONNECTION_DOWN); + new_conn->peer=NULL; /* no true set function for this */ thread=talloc(new_conn, pthread_t); gssctx=talloc(new_conn, gss_ctx_id_t); if (gssctx==NULL) { @@ -334,12 +335,12 @@ TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, unsigned int "trustrouter", &fd, trp_connection_get_gssctx(conn)); - tr_debug("trp_connection_initiate: connected"); - if (err) { + tr_debug("trp_connection_initiate: connection failed."); talloc_free(conn); return TRP_ERROR; } else { + tr_debug("trp_connection_initiate: connected."); trp_connection_set_fd(conn, fd); trp_connection_set_peer(conn); trp_connection_set_status(conn, TRP_CONNECTION_UP); diff --git a/trp/trp_ptable.c b/trp/trp_ptable.c index 8355a8b..4a276d5 100644 --- a/trp/trp_ptable.c +++ b/trp/trp_ptable.c @@ -1,3 +1,4 @@ +#include #include #include @@ -9,10 +10,11 @@ TRP_PEER *trp_peer_new(TALLOC_CTX *memctx) { TRP_PEER *peer=talloc(memctx, TRP_PEER); if (peer!=NULL) { + peer->next=NULL; peer->server=NULL; peer->port=0; peer->linkcost=TRP_METRIC_INFINITY; - peer->next=NULL; + peer->last_conn_attempt=(struct timespec){0,0}; } return peer; } @@ -68,7 +70,10 @@ void trp_peer_set_port(TRP_PEER *peer, unsigned int port) unsigned int trp_peer_get_linkcost(TRP_PEER *peer) { - return peer->linkcost; + if (peer!=NULL) + return peer->linkcost; + else + return 1; } void trp_peer_set_linkcost(TRP_PEER *peer, unsigned int linkcost) @@ -82,6 +87,16 @@ void trp_peer_set_linkcost(TRP_PEER *peer, unsigned int linkcost) peer->linkcost=linkcost; } +struct timespec *trp_peer_get_last_conn_attempt(TRP_PEER *peer) +{ + return &(peer->last_conn_attempt); +} + +void trp_peer_set_last_conn_attempt(TRP_PEER *peer, struct timespec *time) +{ + peer->last_conn_attempt=*time; +} + TRP_PTABLE *trp_ptable_new(TALLOC_CTX *memctx) { TRP_PTABLE *ptbl=talloc(memctx, TRP_PTABLE); @@ -185,8 +200,7 @@ TRP_PEER *trp_ptable_iter_first(TRP_PTABLE_ITER *iter, TRP_PTABLE *ptbl) TRP_PEER *trp_ptable_iter_next(TRP_PTABLE_ITER *iter) { - if ((*iter)->next!=NULL) - *iter=(*iter)->next; + *iter=(*iter)->next; return *iter; } diff --git a/trp/trp_rtable.c b/trp/trp_rtable.c index 20caef7..6fbbd6f 100644 --- a/trp/trp_rtable.c +++ b/trp/trp_rtable.c @@ -64,6 +64,11 @@ TR_NAME *trp_rentry_get_apc(TRP_RENTRY *entry) return entry->apc; } +TR_NAME *trp_rentry_dup_apc(TRP_RENTRY *entry) +{ + return tr_dup_name(trp_rentry_get_apc(entry)); +} + void trp_rentry_set_realm(TRP_RENTRY *entry, TR_NAME *realm) { entry->realm=realm; @@ -74,6 +79,11 @@ TR_NAME *trp_rentry_get_realm(TRP_RENTRY *entry) return entry->realm; } +TR_NAME *trp_rentry_dup_realm(TRP_RENTRY *entry) +{ + return tr_dup_name(trp_rentry_get_realm(entry)); +} + void trp_rentry_set_trust_router(TRP_RENTRY *entry, TR_NAME *tr) { entry->trust_router=tr; @@ -84,6 +94,11 @@ TR_NAME *trp_rentry_get_trust_router(TRP_RENTRY *entry) return entry->trust_router; } +TR_NAME *trp_rentry_dup_trust_router(TRP_RENTRY *entry) +{ + return tr_dup_name(trp_rentry_get_trust_router(entry)); +} + void trp_rentry_set_peer(TRP_RENTRY *entry, TR_NAME *peer) { entry->peer=peer; @@ -94,6 +109,11 @@ TR_NAME *trp_rentry_get_peer(TRP_RENTRY *entry) return entry->peer; } +TR_NAME *trp_rentry_dup_peer(TRP_RENTRY *entry) +{ + return tr_dup_name(trp_rentry_get_peer(entry)); +} + void trp_rentry_set_metric(TRP_RENTRY *entry, unsigned int metric) { entry->metric=metric; @@ -114,6 +134,11 @@ TR_NAME *trp_rentry_get_next_hop(TRP_RENTRY *entry) return entry->next_hop; } +TR_NAME *trp_rentry_dup_next_hop(TRP_RENTRY *entry) +{ + return tr_dup_name(trp_rentry_get_next_hop(entry)); +} + void trp_rentry_set_selected(TRP_RENTRY *entry, int sel) { entry->selected=sel; diff --git a/trp/trp_upd.c b/trp/trp_upd.c index ec829ec..4ef9d41 100644 --- a/trp/trp_upd.c +++ b/trp/trp_upd.c @@ -111,7 +111,7 @@ TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec) static TRP_INFOREC *trp_inforec_get_tail(TRP_INFOREC *rec) { - while (rec!=NULL) + while ((rec->next)!=NULL) rec=trp_inforec_get_next(rec); return rec; } @@ -149,6 +149,11 @@ TR_NAME *trp_inforec_get_comm(TRP_INFOREC *rec) return NULL; } +TR_NAME *trp_inforec_dup_comm(TRP_INFOREC *rec) +{ + return tr_dup_name(trp_inforec_get_comm(rec)); +} + TRP_RC trp_inforec_set_comm(TRP_INFOREC *rec, TR_NAME *comm) { switch (rec->type) { @@ -177,6 +182,11 @@ TR_NAME *trp_inforec_get_realm(TRP_INFOREC *rec) return NULL; } +TR_NAME *trp_inforec_dup_realm(TRP_INFOREC *rec) +{ + return tr_dup_name(trp_inforec_get_realm(rec)); +} + TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm) { switch (rec->type) { @@ -205,6 +215,11 @@ TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec) return NULL; } +TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec) +{ + return tr_dup_name(trp_inforec_get_trust_router(rec)); +} + TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router) { switch (rec->type) { @@ -233,6 +248,11 @@ TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec) return NULL; } +TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec) +{ + return tr_dup_name(trp_inforec_get_next_hop(rec)); +} + TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop) { switch (rec->type) { @@ -387,6 +407,7 @@ void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec) void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec) { + tr_debug("trp_upd_add_inforec: adding record."); if (upd->records==NULL) upd->records=rec; else diff --git a/trp/trpc.c b/trp/trpc.c index 4913455..9fd079f 100644 --- a/trp/trpc.c +++ b/trp/trpc.c @@ -8,6 +8,13 @@ #include #include +static int trpc_destructor(void *object) +{ + TRPC_INSTANCE *trpc=talloc_get_type_abort(object, TRPC_INSTANCE); + if (trpc->gssname!=NULL) + tr_free_name(trpc->gssname); + return 0; +} /* also allocates the incoming mq */ TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx) @@ -23,7 +30,9 @@ TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx) if (trpc->mq==NULL) { talloc_free(trpc); trpc=NULL; - } + } else + talloc_set_destructor((void *)trpc, trpc_destructor); + } return trpc; } @@ -95,6 +104,17 @@ void trpc_set_server(TRPC_INSTANCE *trpc, char *server) trpc->server=server; } +TR_NAME *trpc_get_gssname(TRPC_INSTANCE *trpc) +{ + return trpc->gssname; +} + +/* takes responsibility for freeing gssname */ +void trpc_set_gssname(TRPC_INSTANCE *trpc, TR_NAME *gssname) +{ + trpc->gssname=gssname; +} + unsigned int trpc_get_port(TRPC_INSTANCE *trpc) { return trpc->port; diff --git a/trp/trps.c b/trp/trps.c index 6bddc66..ae177eb 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -75,6 +75,17 @@ void trps_mq_append(TRPS_INSTANCE *trps, TR_MQ_MSG *msg) tr_mq_append(trps->mq, msg); } +unsigned int trps_get_connect_interval(TRPS_INSTANCE *trps) +{ + return trps->connect_interval.tv_sec; +} + +void trps_set_connect_interval(TRPS_INSTANCE *trps, unsigned int interval) +{ + trps->connect_interval.tv_sec=interval; + trps->connect_interval.tv_usec=0; +} + unsigned int trps_get_update_interval(TRPS_INSTANCE *trps) { return trps->update_interval.tv_sec; @@ -97,15 +108,19 @@ void trps_set_sweep_interval(TRPS_INSTANCE *trps, unsigned int interval) trps->sweep_interval.tv_usec=0; } -static TRPC_INSTANCE *trps_find_trpc(TRPS_INSTANCE *trps, TR_NAME *peer_gssname) +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); + for (cur=trps->trpc; cur!=NULL; cur=trpc_get_next(cur)) { - if (0==tr_name_cmp(peer_gssname, - trp_connection_get_gssname(trpc_get_conn(cur)))) { + name=trpc_get_gssname(cur); + if ((name!=NULL) && (0==tr_name_cmp(peer_gssname, name))) { break; } } + tr_free_name(peer_gssname); return cur; } @@ -143,7 +158,7 @@ void trps_remove_trpc(TRPS_INSTANCE *trps, TRPC_INSTANCE *remove) trps->trpc=trpc_remove(trps->trpc, remove); } -TRP_RC trps_send_msg(TRPS_INSTANCE *trps, TR_NAME *peer_gssname, const char *msg) +TRP_RC trps_send_msg(TRPS_INSTANCE *trps, TRP_PEER *peer, const char *msg) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_MQ_MSG *mq_msg=NULL; @@ -152,7 +167,7 @@ TRP_RC trps_send_msg(TRPS_INSTANCE *trps, TR_NAME *peer_gssname, const char *msg TRPC_INSTANCE *trpc=NULL; /* get the connection for this peer */ - trpc=trps_find_trpc(trps, peer_gssname); + trpc=trps_find_trpc(trps, peer); if ((trpc==NULL) || (trpc_get_status(trps->trpc)!=TRP_CONNECTION_UP)) { /* We could just let these sit on the queue in the hopes that a connection * is eventually established. However, we'd then have to ensure the queue @@ -403,8 +418,8 @@ static TRP_RC trps_validate_inforec(TRPS_INSTANCE *trps, TRP_INFOREC *rec) } /* check for valid metric */ - if (trp_metric_is_valid(trp_inforec_get_metric(rec))) { - tr_debug("trps_validate_inforec: invalid metric."); + if (trp_metric_is_invalid(trp_inforec_get_metric(rec))) { + tr_debug("trps_validate_inforec: invalid metric (%u).", trp_inforec_get_metric(rec)); return TRP_ERROR; } @@ -766,6 +781,7 @@ static TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, TRPS_INSTAN result=talloc_array(memctx, TRP_RENTRY *, trp_rtable_size(trps->rtable)); if (result==NULL) { talloc_free(apc); + *n_update=0; return NULL; } @@ -800,9 +816,9 @@ static TRP_INFOREC *trps_rentry_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *t /* Note that we leave the next hop empty since the recipient fills that in. * This is where we add the link cost (currently always 1) to the next peer. */ - if ((trp_inforec_set_comm(rec, trp_rentry_get_apc(entry)) != TRP_SUCCESS) - ||(trp_inforec_set_realm(rec, trp_rentry_get_realm(entry)) != TRP_SUCCESS) - ||(trp_inforec_set_trust_router(rec, trp_rentry_get_trust_router(entry)) != TRP_SUCCESS) + if ((trp_inforec_set_comm(rec, trp_rentry_dup_apc(entry)) != TRP_SUCCESS) + ||(trp_inforec_set_realm(rec, trp_rentry_dup_realm(entry)) != TRP_SUCCESS) + ||(trp_inforec_set_trust_router(rec, trp_rentry_dup_trust_router(entry)) != TRP_SUCCESS) ||(trp_inforec_set_metric(rec, trp_rentry_get_metric(entry)+linkcost) != TRP_SUCCESS) ||(trp_inforec_set_interval(rec, trps_get_update_interval(trps)) != TRP_SUCCESS)) { tr_err("trps_rentry_to_inforec: error creating route update."); @@ -825,6 +841,7 @@ TRP_RC trps_scheduled_update(TRPS_INSTANCE *trps) size_t n_updates=0, ii=0; char *encoded=NULL; TRP_RC rc=TRP_ERROR; + TR_NAME *peer_gssname=NULL; if (iter==NULL) { tr_err("trps_scheduled_update: failed to allocate peer table iterator."); @@ -836,44 +853,48 @@ TRP_RC trps_scheduled_update(TRPS_INSTANCE *trps) peer!=NULL; peer=trp_ptable_iter_next(iter)) { - tr_debug("trps_scheduled_update: preparing scheduled route update for %.*%s", - trp_peer_get_gssname(peer)->len, trp_peer_get_gssname(peer)->buf); - upd=trp_upd_new(tmp_ctx); + peer_gssname=trp_peer_get_gssname(peer); + tr_debug("trps_scheduled_update: preparing scheduled route update for %.*s", + peer_gssname->len, peer_gssname->buf); /* do not fill in peer, recipient does that */ - update_list=trps_select_updates_for_peer(tmp_ctx, trps, trp_peer_get_gssname(peer), &n_updates); - for (ii=0; ii0) && (update_list!=NULL)) { + tr_debug("trps_scheduled_update: sending %u update records.", (unsigned int)n_updates); + upd=trp_upd_new(tmp_ctx); + + for (ii=0; ii