From bdfe6a5b5ad57649ca51d902aec87ab4e85a3a58 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Mon, 18 Jul 2016 15:43:12 -0400 Subject: [PATCH] Generate scheduled updates. Untested, but builds. --- common/tr_config.c | 9 +++ include/tr_cfgwatch.h | 7 +- include/tr_config.h | 2 + include/tr_trp.h | 2 + include/trp_internal.h | 11 ++- include/trp_ptable.h | 9 +++ include/trust_router/trp.h | 1 + tr/tr_cfgwatch.c | 7 +- tr/tr_main.c | 2 + tr/tr_trp.c | 80 +++++++++++++++++---- trp/trp_ptable.c | 34 +++++++++ trp/trp_upd.c | 16 +++++ trp/trps.c | 169 +++++++++++++++++++++++++++++++++++++++------ 13 files changed, 306 insertions(+), 43 deletions(-) diff --git a/common/tr_config.c b/common/tr_config.c index 59fd409..6a3d4dc 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -97,6 +97,7 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) { json_t *jcfgpoll = NULL; json_t *jcfgsettle = NULL; json_t *jroutesweep = NULL; + json_t *jrouteupdate = NULL; if ((!trc) || (!jcfg)) return TR_CFG_BAD_PARAMS; @@ -172,6 +173,14 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) { return TR_CFG_NOPARSE; } } + if (NULL != (jrouteupdate = json_object_get(jint, "route_update_interval"))) { + if (json_is_number(jrouteupdate)) { + trc->internal->route_update_interval = json_integer_value(jrouteupdate); + } else { + tr_debug("tr_cfg_parse_internal: Parsing error, route_update_interval is not a number."); + return TR_CFG_NOPARSE; + } + } if (NULL != (jlog = json_object_get(jint, "logging"))) { if (NULL != (jlogthres = json_object_get(jlog, "log_threshold"))) { diff --git a/include/tr_cfgwatch.h b/include/tr_cfgwatch.h index 434202f..b8a873e 100644 --- a/include/tr_cfgwatch.h +++ b/include/tr_cfgwatch.h @@ -11,7 +11,7 @@ struct tr_fstat { struct timespec mtime; }; -struct tr_cfgwatch_data { +typedef struct tr_cfgwatch_data { struct timeval poll_interval; /* how often should we check for updates? */ struct timeval settling_time; /* how long should we wait for changes to settle before updating? */ char *config_dir; /* what directory are we watching? */ @@ -20,8 +20,9 @@ struct tr_cfgwatch_data { int change_detected; /* have we detected a change? */ struct timeval last_change_detected; /* when did we last note a changed mtime? */ TR_CFG_MGR *cfg_mgr; /* what trust router config are we updating? */ -}; -typedef struct tr_cfgwatch_data TR_CFGWATCH; + void (*update_cb)(TR_CFG *new_cfg, void *cookie); /* callback after config updated */ + void *update_cookie; /* data for the update_cb() */ +} TR_CFGWATCH; /* prototypes */ diff --git a/include/tr_config.h b/include/tr_config.h index 737da4b..6cffb00 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,7 @@ typedef struct tr_cfg_internal { unsigned int cfg_poll_interval; unsigned int cfg_settle_count; unsigned int route_sweep_interval; + unsigned int route_update_interval; } TR_CFG_INTERNAL; typedef struct tr_cfg { diff --git a/include/tr_trp.h b/include/tr_trp.h index 7b12672..53033f6 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 *update_ev; struct event *sweep_ev; } TR_TRPS_EVENTS; @@ -20,4 +21,5 @@ 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); +void tr_config_changed(TR_CFG *new_cfg, void *cookie); #endif /* TR_TRP_H */ diff --git a/include/trp_internal.h b/include/trp_internal.h index 151139b..5151075 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -95,6 +95,8 @@ struct trps_instance { TR_MQ *mq; /* incoming message queue */ TRP_PTABLE *ptable; /* peer table */ TRP_RTABLE *rtable; /* route table */ + struct timeval update_interval; /* interval between scheduled updates */ + struct timeval sweep_interval; /* interval between route table sweeps */ }; @@ -146,7 +148,11 @@ 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); -TRP_RC trps_send_msg (TRPS_INSTANCE *trps, void *peer, const char *msg); +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); 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); @@ -166,6 +172,7 @@ TRP_RENTRY *trps_get_selected_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME TR_NAME *trps_get_next_hop(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm); TRP_RC trps_sweep_routes(TRPS_INSTANCE *trps); TRP_RC trps_add_peer(TRPS_INSTANCE *trps, TRP_PEER *peer); -TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, TRPS_INSTANCE *trps, TR_NAME *peer_gssname, size_t *n_update); +TRP_PEER *trps_get_peer(TRPS_INSTANCE *trps, TR_NAME *gssname); +TRP_RC trps_scheduled_update(TRPS_INSTANCE *trps); #endif /* TRP_INTERNAL_H */ diff --git a/include/trp_ptable.h b/include/trp_ptable.h index 762ba02..23d729d 100644 --- a/include/trp_ptable.h +++ b/include/trp_ptable.h @@ -18,12 +18,21 @@ typedef struct trp_ptable { TRP_PEER *head; /* head of a peer table list */ } TRP_PTABLE; +/* iterator for the peer table */ +typedef TRP_PEER *TRP_PTABLE_ITER; + TRP_PTABLE *trp_ptable_new(TALLOC_CTX *memctx); void trp_ptable_free(TRP_PTABLE *ptbl); TRP_RC trp_ptable_add(TRP_PTABLE *ptbl, TRP_PEER *newpeer); TRP_RC trp_ptable_remove(TRP_PTABLE *ptbl, TRP_PEER *peer); +TRP_PEER *trp_ptable_find(TRP_PTABLE *ptbl, TR_NAME *gssname); char *trp_ptable_to_str(TALLOC_CTX *memctx, TRP_PTABLE *ptbl, const char *sep, const char *lineterm); +TRP_PTABLE_ITER *trp_ptable_iter_new(TALLOC_CTX *mem_ctx); +TRP_PEER *trp_ptable_iter_first(TRP_PTABLE_ITER *iter, TRP_PTABLE *ptbl); +TRP_PEER *trp_ptable_iter_next(TRP_PTABLE_ITER *iter); +void trp_ptable_iter_free(TRP_PTABLE_ITER *iter); + TRP_PEER *trp_peer_new(TALLOC_CTX *memctx); void trp_peer_free(TRP_PEER *peer); char *trp_peer_get_server(TRP_PEER *peer); diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h index acd39ef..a267fd1 100644 --- a/include/trust_router/trp.h +++ b/include/trust_router/trp.h @@ -38,6 +38,7 @@ TR_EXPORT TRP_UPD *trp_upd_new(TALLOC_CTX *mem_ctx); void trp_upd_free(TRP_UPD *update); TR_EXPORT TRP_INFOREC *trp_upd_get_inforec(TRP_UPD *upd); void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec); +void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec); TR_EXPORT TR_NAME *trp_upd_get_peer(TRP_UPD *upd); void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer); TR_EXPORT TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type); diff --git a/tr/tr_cfgwatch.c b/tr/tr_cfgwatch.c index 6e98651..ff5eb77 100644 --- a/tr/tr_cfgwatch.c +++ b/tr/tr_cfgwatch.c @@ -233,11 +233,14 @@ static void tr_cfgwatch_event_cb(int listener, short event, void *arg) } timersub(&now, &cfg_status->last_change_detected, &diff); if (!timercmp(&diff, &cfg_status->settling_time, <)) { - tr_notice("Configuration file change settled, updating configuration."); + 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 + else { + if (cfg_status->update_cb!=NULL) + cfg_status->update_cb(cfg_status->cfg_mgr->active, cfg_status->update_cookie); tr_notice("Configuration updated successfully."); + } cfg_status->change_detected=0; } } diff --git a/tr/tr_main.c b/tr/tr_main.c index b4669ed..411ee04 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -223,6 +223,8 @@ int main(int argc, char *argv[]) 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))) { diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 492fc5d..db66571 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -16,10 +16,11 @@ #include #include -/* hold a trps instance and a config manager */ +/* data for event callbacks */ struct tr_trps_event_cookie { TRPS_INSTANCE *trps; TR_CFG_MGR *cfg_mgr; + struct event *ev; }; /* callback to schedule event to process messages */ @@ -196,11 +197,27 @@ static void tr_trps_process_mq(int socket, short event, void *arg) } } +static void tr_trps_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_trps_update: sending scheduled route updates."); + trps_scheduled_update(trps); + event_add(ev, &(trps->update_interval)); +} + static void tr_trps_sweep(int listener, short event, void *arg) { - TRPS_INSTANCE *trps=talloc_get_type_abort(arg, TRPS_INSTANCE); + 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_trps_sweep: sweeping routes"); trps_sweep_routes(trps); + /* schedule the event to run again */ + event_add(ev, &(trps->sweep_interval)); } static int tr_trps_events_destructor(void *obj) @@ -218,6 +235,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->update_ev=NULL; ev->sweep_ev=NULL; if (ev->listen_ev==NULL) { talloc_free(ev); @@ -237,8 +255,9 @@ 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 *cookie; - struct timeval two_secs={2, 0}; + struct tr_trps_event_cookie *trps_cookie=NULL; + struct tr_trps_event_cookie *update_cookie=NULL; + struct tr_trps_event_cookie *sweep_cookie=NULL; TRP_RC retval=TRP_ERROR; if (trps_ev == NULL) { @@ -252,15 +271,15 @@ TRP_RC tr_trps_event_init(struct event_base *base, /* Create the cookie for callbacks. It is part of the trps context, so it will * be cleaned up when trps is freed by talloc_free. */ - cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); - if (cookie == NULL) { - tr_debug("tr_trps_event_init: Unable to allocate cookie."); + trps_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + if (trps_cookie == NULL) { + tr_debug("tr_trps_event_init: Unable to allocate trps_cookie."); retval=TRP_NOMEM; goto cleanup; } - cookie->trps=trps; - cookie->cfg_mgr=cfg_mgr; - talloc_steal(trps, cookie); + trps_cookie->trps=trps; + trps_cookie->cfg_mgr=cfg_mgr; + talloc_steal(trps, trps_cookie); /* get a trps listener */ listen_ev->sock_fd=trps_get_listener(trps, @@ -268,12 +287,13 @@ TRP_RC tr_trps_event_init(struct event_base *base, tr_trps_gss_handler, cfg_mgr->active->internal->hostname, cfg_mgr->active->internal->trps_port, - (void *)cookie); + (void *)trps_cookie); if (listen_ev->sock_fd < 0) { tr_crit("Error opening TRP server socket."); retval=TRP_ERROR; goto cleanup; } + trps_cookie->ev=listen_ev->ev; /* in case it needs to frob the event */ /* and its event */ listen_ev->ev=event_new(base, @@ -292,10 +312,33 @@ 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 route update timer event */ + update_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + if (update_cookie == NULL) { + tr_debug("tr_trps_event_init: Unable to allocate update_cookie."); + retval=TRP_NOMEM; + goto cleanup; + } + update_cookie->trps=trps; + update_cookie->cfg_mgr=cfg_mgr; + talloc_steal(trps, update_cookie); + trps_ev->update_ev=event_new(base, -1, EV_TIMEOUT, tr_trps_update, (void *)update_cookie); + update_cookie->ev=trps_ev->update_ev; /* in case it needs to frob the event */ + event_add(trps_ev->update_ev, &(trps->update_interval)); + /* now set up the route table sweep timer event */ - trps_ev->sweep_ev=event_new(base, -1, EV_TIMEOUT|EV_PERSIST, tr_trps_sweep, (void *)trps); - /* todo: event_add(trps_ev->sweep_ev, &(cfg_mgr->active->internal->route_sweep_interval)); */ - event_add(trps_ev->sweep_ev, &two_secs); + sweep_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + if (sweep_cookie == NULL) { + tr_debug("tr_trps_event_init: Unable to allocate sweep_cookie."); + retval=TRP_NOMEM; + goto cleanup; + } + sweep_cookie->trps=trps; + sweep_cookie->cfg_mgr=cfg_mgr; + talloc_steal(trps, sweep_cookie); + trps_ev->sweep_ev=event_new(base, -1, EV_TIMEOUT, tr_trps_sweep, (void *)sweep_cookie); + sweep_cookie->ev=trps_ev->sweep_ev; /* in case it needs to frob the event */ + event_add(trps_ev->sweep_ev, &(trps->sweep_interval)); retval=TRP_SUCCESS; @@ -455,3 +498,12 @@ TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, const char *server, unsigne talloc_free(tmp_ctx); return trpc; } + +/* 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); +} diff --git a/trp/trp_ptable.c b/trp/trp_ptable.c index c6c1cb8..8355a8b 100644 --- a/trp/trp_ptable.c +++ b/trp/trp_ptable.c @@ -132,6 +132,14 @@ TRP_RC trp_ptable_remove(TRP_PTABLE *ptbl, TRP_PEER *peer) return TRP_ERROR; } +TRP_PEER *trp_ptable_find(TRP_PTABLE *ptbl, TR_NAME *gssname) +{ + TRP_PEER *cur=ptbl->head; + while ((cur!=NULL) && (0 != tr_name_cmp(trp_peer_get_gssname(cur), gssname))) + cur=cur->next; + return cur; +} + char *trp_peer_to_str(TALLOC_CTX *memctx, TRP_PEER *peer, const char *sep) { if (sep==NULL) @@ -161,3 +169,29 @@ char *trp_ptable_to_str(TALLOC_CTX *memctx, TRP_PTABLE *ptbl, const char *sep, c talloc_free(tmpctx); /* free detritus */ return result; } + +TRP_PTABLE_ITER *trp_ptable_iter_new(TALLOC_CTX *mem_ctx) +{ + TRP_PTABLE_ITER *iter=talloc(mem_ctx, TRP_PTABLE_ITER); + *iter=NULL; + return iter; +} + +TRP_PEER *trp_ptable_iter_first(TRP_PTABLE_ITER *iter, TRP_PTABLE *ptbl) +{ + *iter=ptbl->head; + return *iter; +} + +TRP_PEER *trp_ptable_iter_next(TRP_PTABLE_ITER *iter) +{ + if ((*iter)->next!=NULL) + *iter=(*iter)->next; + return *iter; +} + +void trp_ptable_iter_free(TRP_PTABLE_ITER *iter) +{ + talloc_free(iter); +} + diff --git a/trp/trp_upd.c b/trp/trp_upd.c index 6865a44..ec829ec 100644 --- a/trp/trp_upd.c +++ b/trp/trp_upd.c @@ -109,6 +109,13 @@ TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec) return NULL; } +static TRP_INFOREC *trp_inforec_get_tail(TRP_INFOREC *rec) +{ + while (rec!=NULL) + rec=trp_inforec_get_next(rec); + return rec; +} + void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec) { if (rec !=NULL) @@ -378,6 +385,15 @@ void trp_upd_set_inforec(TRP_UPD *upd, TRP_INFOREC *rec) upd->records=rec; } +void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec) +{ + if (upd->records==NULL) + upd->records=rec; + else + trp_inforec_set_next(trp_inforec_get_tail(upd->records), rec); + talloc_steal(upd, rec); +} + TR_NAME *trp_upd_get_peer(TRP_UPD *upd) { return upd->peer; diff --git a/trp/trps.c b/trp/trps.c index 4596807..6bddc66 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,8 @@ TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx) trps->cookie=NULL; trps->conn=NULL; trps->trpc=NULL; + trps->update_interval=(struct timeval){0,0}; + trps->sweep_interval=(struct timeval){0,0}; trps->mq=tr_mq_new(trps); if (trps->mq==NULL) { @@ -72,17 +75,39 @@ void trps_mq_append(TRPS_INSTANCE *trps, TR_MQ_MSG *msg) tr_mq_append(trps->mq, msg); } -#if 0 -static TRP_CONNECTION *trps_find_conn(TRPS_INSTANCE *trps, TR_NAME *peer_gssname) +unsigned int trps_get_update_interval(TRPS_INSTANCE *trps) { - TRP_CONNECTION *cur=NULL; - for (cur=trps->conn; cur!=NULL; cur=trp_connection_get_next(cur)) { - if (0==tr_name_cmp(peer_gssname, trp_connection_get_gssname(cur))) + return trps->update_interval.tv_sec; +} + +void trps_set_update_interval(TRPS_INSTANCE *trps, unsigned int interval) +{ + trps->update_interval.tv_sec=interval; + trps->update_interval.tv_usec=0; +} + +unsigned int trps_get_sweep_interval(TRPS_INSTANCE *trps) +{ + return trps->sweep_interval.tv_sec; +} + +void trps_set_sweep_interval(TRPS_INSTANCE *trps, unsigned int interval) +{ + trps->sweep_interval.tv_sec=interval; + trps->sweep_interval.tv_usec=0; +} + +static TRPC_INSTANCE *trps_find_trpc(TRPS_INSTANCE *trps, TR_NAME *peer_gssname) +{ + TRPC_INSTANCE *cur=NULL; + 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)))) { break; + } } return cur; } -#endif void trps_add_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *new) { @@ -118,26 +143,27 @@ 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, void *peer, const char *msg) +TRP_RC trps_send_msg(TRPS_INSTANCE *trps, TR_NAME *peer_gssname, const char *msg) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_MQ_MSG *mq_msg=NULL; char *msg_dup=NULL; TRP_RC rc=TRP_ERROR; - - /* Currently ignore peer and just send to an open connection. - * In reality, need to identify the correct peer and send via that - * one. */ - if (trps->trpc != NULL) { - if (trpc_get_status(trps->trpc)!=TRP_CONNECTION_UP) - tr_debug("trps_send_msg: skipping message sent while TRPC connection not up."); - else { - mq_msg=tr_mq_msg_new(tmp_ctx, "trpc_send"); - msg_dup=talloc_strdup(mq_msg, msg); /* get local copy in mq_msg context */ - tr_mq_msg_set_payload(mq_msg, msg_dup, NULL); /* no need for a free() func */ - trpc_mq_append(trps->trpc, mq_msg); - rc=TRP_SUCCESS; - } + TRPC_INSTANCE *trpc=NULL; + + /* get the connection for this peer */ + trpc=trps_find_trpc(trps, peer_gssname); + 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 + * didn't keep growing, etc. */ + tr_warning("trps_send_msg: skipping message queued while TRPC connection not up."); + } else { + mq_msg=tr_mq_msg_new(tmp_ctx, "trpc_send"); + msg_dup=talloc_strdup(mq_msg, msg); /* get local copy in mq_msg context */ + tr_mq_msg_set_payload(mq_msg, msg_dup, NULL); /* no need for a free() func */ + trpc_mq_append(trpc, mq_msg); + rc=TRP_SUCCESS; } talloc_free(tmp_ctx); return rc; @@ -722,7 +748,7 @@ static TRP_RENTRY *trps_select_realm_update(TRPS_INSTANCE *trps, TR_NAME *comm, /* returns an array of pointers to updates (*not* an array of updates). Returns number of entries * via n_update parameter. (The allocated space will generally be larger than required, see note in * the code.) */ -TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, TRPS_INSTANCE *trps, TR_NAME *peer_gssname, size_t *n_update) +static TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, TRPS_INSTANCE *trps, TR_NAME *peer_gssname, size_t *n_update) { size_t n_apc=0; TR_NAME **apc=trp_rtable_get_apcs(trps->rtable, &n_apc); @@ -762,7 +788,106 @@ TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, TRPS_INSTANCE *trp return result; } +/* convert an rentry into a new trp update info record */ +static TRP_INFOREC *trps_rentry_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trps, TRP_RENTRY *entry) +{ + TRP_INFOREC *rec=trp_inforec_new(mem_ctx, TRP_INFOREC_TYPE_ROUTE); + unsigned int linkcost=0; + + if (rec!=NULL) { + linkcost=trp_peer_get_linkcost(trps_get_peer(trps, + trp_rentry_get_next_hop(entry))); + + /* 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) + ||(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."); + talloc_free(rec); + rec=NULL; + } + } + return rec; +} + +TRP_RC trps_scheduled_update(TRPS_INSTANCE *trps) +{ + TALLOC_CTX *tmp_ctx=talloc_new(NULL); + TRP_PTABLE_ITER *iter=trp_ptable_iter_new(tmp_ctx); + TRP_PEER *peer=NULL; + TR_MSG msg; /* not a pointer! */ + TRP_UPD *upd=NULL; + TRP_RENTRY **update_list=NULL; + TRP_INFOREC *rec=NULL; + size_t n_updates=0, ii=0; + char *encoded=NULL; + TRP_RC rc=TRP_ERROR; + + if (iter==NULL) { + tr_err("trps_scheduled_update: failed to allocate peer table iterator."); + talloc_free(tmp_ctx); + return TRP_NOMEM; + } + + for (peer=trp_ptable_iter_first(iter, trps->ptable); + 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); + /* 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; iiptable, peer); } + +TRP_PEER *trps_get_peer(TRPS_INSTANCE *trps, TR_NAME *gssname) +{ + return trp_ptable_find(trps->ptable, gssname); +} -- 2.1.4