From 9828a0554c2fa3901ec8c4ed039bfebc807fb8a5 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Tue, 2 Aug 2016 11:29:12 -0400 Subject: [PATCH] Fix memory freeing bugs. Seems stable, even through loss of connections. --- common/tr_config.c | 14 ++- common/tr_name.c | 4 +- include/tr.h | 8 +- include/tr_cfgwatch.h | 6 ++ include/tr_config.h | 2 +- include/tr_trp.h | 19 +++- include/trp_internal.h | 16 ++- include/trp_rtable.h | 77 ++++++++------- include/trust_router/trp.h | 2 + tr/tr.c | 2 +- tr/tr_main.c | 43 +++++--- tr/tr_trp.c | 212 ++++++++++++++++++++++------------------ tr/trpc_main.c | 28 +++--- trp/trp_conn.c | 13 ++- trp/trp_ptable.c | 2 +- trp/trp_rtable.c | 153 +++++++++++++++++------------ trp/trpc.c | 11 --- trp/trps.c | 239 +++++++++++++++++++++++++-------------------- 18 files changed, 483 insertions(+), 368 deletions(-) diff --git a/common/tr_config.c b/common/tr_config.c index 4d05d4b..514a300 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -38,11 +38,12 @@ #include #include +#include #include #include -#include #include #include +#include void tr_print_config (FILE *stream, TR_CFG *cfg) { fprintf(stream, "tr_print_config: Not yet implemented."); @@ -157,14 +158,19 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) { tr_debug("tr_cfg_parse_internal: Parsing error, cfg_poll_interval is not a number."); return TR_CFG_NOPARSE; } + } else { + trc->internal->cfg_poll_interval = TR_CFGWATCH_DEFAULT_POLL; } - if (NULL != (jcfgsettle = json_object_get(jint, "cfg_settle_count"))) { + + if (NULL != (jcfgsettle = json_object_get(jint, "cfg_settling_time"))) { if (json_is_number(jcfgsettle)) { - trc->internal->cfg_settle_count = json_integer_value(jcfgsettle); + trc->internal->cfg_settling_time = json_integer_value(jcfgsettle); } else { - tr_debug("tr_cfg_parse_internal: Parsing error, cfg_settle_count is not a number."); + tr_debug("tr_cfg_parse_internal: Parsing error, cfg_settling_time is not a number."); return TR_CFG_NOPARSE; } + } else { + trc->internal->cfg_settling_time = TR_CFGWATCH_DEFAULT_SETTLE; } if (NULL != (jrouteconnect = json_object_get(jint, "trp_connect_interval"))) { diff --git a/common/tr_name.c b/common/tr_name.c index 41cad47..e048731 100644 --- a/common/tr_name.c +++ b/common/tr_name.c @@ -55,6 +55,9 @@ TR_NAME *tr_new_name (char *name) new->len = strlen(name); if (new->buf = malloc((new->len)+1)) { strcpy(new->buf, name); + } else { + free(new); + new=NULL; } } return new; @@ -120,4 +123,3 @@ char * tr_name_strdup(TR_NAME *src) return s; } - diff --git a/include/tr.h b/include/tr.h index 8878161..bd55176 100644 --- a/include/tr.h +++ b/include/tr.h @@ -45,12 +45,8 @@ #include #include -typedef struct tr_instance { - TR_CFG_MGR *cfg_mgr; - TIDS_INSTANCE *tids; - TRPS_INSTANCE *trps; - TR_CFGWATCH *cfgwatch; -} TR_INSTANCE; +/* struct defined in tr_trp.h */ +typedef struct tr_instance TR_INSTANCE; TR_INSTANCE *tr_create(TALLOC_CTX *mem_ctx); void tr_destroy(TR_INSTANCE *tr); diff --git a/include/tr_cfgwatch.h b/include/tr_cfgwatch.h index b8a873e..3d26048 100644 --- a/include/tr_cfgwatch.h +++ b/include/tr_cfgwatch.h @@ -5,6 +5,12 @@ #include #include +#include +#include +/* interval in seconds */ +#define TR_CFGWATCH_DEFAULT_POLL 1 +#define TR_CFGWATCH_DEFAULT_SETTLE 5 +/* note: settling time is minimum - only checked on poll intervals */ struct tr_fstat { char *name; diff --git a/include/tr_config.h b/include/tr_config.h index 626b20b..448e3e4 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -71,7 +71,7 @@ typedef struct tr_cfg_internal { int log_threshold; int console_threshold; unsigned int cfg_poll_interval; - unsigned int cfg_settle_count; + unsigned int cfg_settling_time; unsigned int trp_sweep_interval; unsigned int trp_update_interval; unsigned int trp_connect_interval; diff --git a/include/tr_trp.h b/include/tr_trp.h index 2e5e00d..bb055fc 100644 --- a/include/tr_trp.h +++ b/include/tr_trp.h @@ -5,11 +5,14 @@ #include #include +#include #include #include +#include #include typedef struct tr_trps_events { + struct event *trps_ev; struct tr_socket_event *listen_ev; struct event *mq_ev; struct event *connect_ev; @@ -17,7 +20,17 @@ typedef struct tr_trps_events { struct event *sweep_ev; } TR_TRPS_EVENTS; +/* typedef'ed as TR_INSTANCE in tr.h */ +struct tr_instance { + TR_CFG_MGR *cfg_mgr; + TIDS_INSTANCE *tids; + TRPS_INSTANCE *trps; + TR_CFGWATCH *cfgwatch; + TR_TRPS_EVENTS *events; +}; + /* messages between threads */ +#define TR_MQMSG_MSG_RECEIVED "msg received" #define TR_MQMSG_TRPC_DISCONNECTED "trpc disconnected" #define TR_MQMSG_TRPC_CONNECTED "trpc connected" #define TR_MQMSG_TRPS_DISCONNECTED "trps disconnected" @@ -25,11 +38,9 @@ typedef struct tr_trps_events { #define TR_MQMSG_ABORT "abort" /* prototypes */ -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); +TRP_RC tr_trps_event_init(struct event_base *base, struct tr_instance *tr); TRP_RC tr_add_local_routes(TRPS_INSTANCE *trps, TR_CFG *cfg); -TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer); +TRP_RC 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 6bb827e..943e4cd 100644 --- a/include/trp_internal.h +++ b/include/trp_internal.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -51,7 +50,9 @@ struct trp_req { typedef struct trps_instance TRPS_INSTANCE; typedef enum trp_connection_status { - TRP_CONNECTION_DOWN=0, + TRP_CONNECTION_CLOSED=0, + TRP_CONNECTION_DOWN, + TRP_CONNECTION_AUTHORIZING, TRP_CONNECTION_UP, TRP_CONNECTION_UNKNOWN, } TRP_CONNECTION_STATUS; @@ -63,7 +64,7 @@ struct trp_connection { pthread_t *thread; /* thread servicing this connection */ int fd; TR_NAME *gssname; - TR_NAME *peer; + TR_NAME *peer; /* TODO: why is there a peer and a gssname? jlr */ gss_ctx_id_t *gssctx; TRP_CONNECTION_STATUS status; void (*status_change_cb)(TRP_CONNECTION *conn, void *cookie); @@ -84,7 +85,6 @@ struct trpc_instance { unsigned int port; TRP_CONNECTION *conn; TR_MQ *mq; /* msgs from master to trpc */ - DH *dh; /* Client's DH struct with priv and pub keys */ }; /* TRP Server Instance Data */ @@ -145,8 +145,6 @@ 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); -void trpc_set_dh(TRPC_INSTANCE *trpc, DH *dh); TRP_CONNECTION_STATUS trpc_get_status(TRPC_INSTANCE *trpc); TR_MQ *trpc_get_mq(TRPC_INSTANCE *trpc); void trpc_set_mq(TRPC_INSTANCE *trpc, TR_MQ *mq); @@ -184,11 +182,11 @@ void trps_mq_append(TRPS_INSTANCE *trps, TR_MQ_MSG *msg); void trps_handle_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *conn); TRP_RC trps_update_active_routes(TRPS_INSTANCE *trps); TRP_RC trps_handle_tr_msg(TRPS_INSTANCE *trps, TR_MSG *tr_msg); -TRP_RENTRY *trps_get_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer); -TRP_RENTRY *trps_get_selected_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm); +TRP_ROUTE *trps_get_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer); +TRP_ROUTE *trps_get_selected_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm); 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_route(TRPS_INSTANCE *trps, TRP_RENTRY *route); +TRP_RC trps_add_route(TRPS_INSTANCE *trps, TRP_ROUTE *route); TRP_RC trps_add_peer(TRPS_INSTANCE *trps, TRP_PEER *peer); TRP_PEER *trps_get_peer(TRPS_INSTANCE *trps, TR_NAME *gssname); TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE type); diff --git a/include/trp_rtable.h b/include/trp_rtable.h index 1dde034..7ccbfb3 100644 --- a/include/trp_rtable.h +++ b/include/trp_rtable.h @@ -7,7 +7,7 @@ #include -typedef struct trp_rentry { +typedef struct trp_route { TR_NAME *apc; TR_NAME *realm; TR_NAME *peer; @@ -17,57 +17,60 @@ typedef struct trp_rentry { int selected; unsigned int interval; /* interval from route update */ struct timespec *expiry; + int local; /* is this a local route? */ int triggered; -} TRP_RENTRY; +} TRP_ROUTE; typedef GHashTable TRP_RTABLE; TRP_RTABLE *trp_rtable_new(void); void trp_rtable_free(TRP_RTABLE *rtbl); -void trp_rtable_add(TRP_RTABLE *rtbl, TRP_RENTRY *entry); /* adds or updates */ -void trp_rtable_remove(TRP_RTABLE *rtbl, TRP_RENTRY *entry); +void trp_rtable_add(TRP_RTABLE *rtbl, TRP_ROUTE *entry); /* adds or updates */ +void trp_rtable_remove(TRP_RTABLE *rtbl, TRP_ROUTE *entry); void trp_rtable_clear(TRP_RTABLE *rtbl); size_t trp_rtable_size(TRP_RTABLE *rtbl); size_t trp_rtable_apc_size(TRP_RTABLE *rtbl, TR_NAME *apc); size_t trp_rtable_realm_size(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm); -TRP_RENTRY **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out); +TRP_ROUTE **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out); TR_NAME **trp_rtable_get_apcs(TRP_RTABLE *rtbl, size_t *n_out); -TRP_RENTRY **trp_rtable_get_apc_entries(TRP_RTABLE *rtbl, TR_NAME *apc, size_t *n_out); +TRP_ROUTE **trp_rtable_get_apc_entries(TRP_RTABLE *rtbl, TR_NAME *apc, size_t *n_out); TR_NAME **trp_rtable_get_apc_realms(TRP_RTABLE *rtbl, TR_NAME *apc, size_t *n_out); -TRP_RENTRY **trp_rtable_get_realm_entries(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, size_t *n_out); +TRP_ROUTE **trp_rtable_get_realm_entries(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, size_t *n_out); TR_NAME **trp_rtable_get_apc_realm_peers(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, size_t *n_out); -TRP_RENTRY *trp_rtable_get_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, TR_NAME *peer); -TRP_RENTRY *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm); +TRP_ROUTE *trp_rtable_get_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, TR_NAME *peer); +TRP_ROUTE *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm); void trp_rtable_clear_triggered(TRP_RTABLE *rtbl); char *trp_rtable_to_str(TALLOC_CTX *mem_ctx, TRP_RTABLE *rtbl, const char *sep, const char *lineterm); -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); -int trp_rentry_get_interval(TRP_RENTRY *entry); -void trp_rentry_set_expiry(TRP_RENTRY *entry, struct timespec *exp); -struct timespec *trp_rentry_get_expiry(TRP_RENTRY *entry); -void trp_rentry_set_triggered(TRP_RENTRY *entry, int trig); -int trp_rentry_get_triggered(TRP_RENTRY *entry); -char *trp_rentry_to_str(TALLOC_CTX *mem_ctx, TRP_RENTRY *entry, const char *sep); +TRP_ROUTE *trp_route_new(TALLOC_CTX *mem_ctx); +void trp_route_free(TRP_ROUTE *entry); +void trp_route_set_apc(TRP_ROUTE *entry, TR_NAME *apc); +TR_NAME *trp_route_get_apc(TRP_ROUTE *entry); +TR_NAME *trp_route_dup_apc(TRP_ROUTE *entry); +void trp_route_set_realm(TRP_ROUTE *entry, TR_NAME *realm); +TR_NAME *trp_route_get_realm(TRP_ROUTE *entry); +TR_NAME *trp_route_dup_realm(TRP_ROUTE *entry); +void trp_route_set_trust_router(TRP_ROUTE *entry, TR_NAME *tr); +TR_NAME *trp_route_get_trust_router(TRP_ROUTE *entry); +TR_NAME *trp_route_dup_trust_router(TRP_ROUTE *entry); +void trp_route_set_peer(TRP_ROUTE *entry, TR_NAME *peer); +TR_NAME *trp_route_get_peer(TRP_ROUTE *entry); +TR_NAME *trp_route_dup_peer(TRP_ROUTE *entry); +void trp_route_set_metric(TRP_ROUTE *entry, unsigned int metric); +unsigned int trp_route_get_metric(TRP_ROUTE *entry); +void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop); +TR_NAME *trp_route_get_next_hop(TRP_ROUTE *entry); +TR_NAME *trp_route_dup_next_hop(TRP_ROUTE *entry); +void trp_route_set_selected(TRP_ROUTE *entry, int sel); +int trp_route_is_selected(TRP_ROUTE *entry); +void trp_route_set_interval(TRP_ROUTE *entry, int interval); +int trp_route_get_interval(TRP_ROUTE *entry); +void trp_route_set_expiry(TRP_ROUTE *entry, struct timespec *exp); +struct timespec *trp_route_get_expiry(TRP_ROUTE *entry); +void trp_route_set_local(TRP_ROUTE *entry, int local); +int trp_route_is_local(TRP_ROUTE *entry); +void trp_route_set_triggered(TRP_ROUTE *entry, int trig); +int trp_route_is_triggered(TRP_ROUTE *entry); +char *trp_route_to_str(TALLOC_CTX *mem_ctx, TRP_ROUTE *entry, const char *sep); #endif /* _TRP_RTABLE_H_ */ diff --git a/include/trust_router/trp.h b/include/trust_router/trp.h index c544f9f..0d998d1 100644 --- a/include/trust_router/trp.h +++ b/include/trust_router/trp.h @@ -12,6 +12,8 @@ #define trp_metric_is_invalid(x) (((x)>TRP_METRIC_INFINITY) || ((x)==TRP_METRIC_INVALID)) #define TRP_INTERVAL_INVALID 0 +#define TRP_LINKCOST_DEFAULT 1 + typedef enum trp_rc { TRP_SUCCESS=0, TRP_ERROR, /* generic error */ diff --git a/tr/tr.c b/tr/tr.c index bd3ce0a..d79ca76 100644 --- a/tr/tr.c +++ b/tr/tr.c @@ -35,8 +35,8 @@ #include #include #include -#include #include +#include TR_INSTANCE *tr_create(TALLOC_CTX *mem_ctx) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); diff --git a/tr/tr_main.c b/tr/tr_main.c index f022fa7..5989f0b 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -39,14 +39,16 @@ #include #include #include +#include +#include -#include #include #include #include #include #include #include +#include #include #define TALLOC_DEBUG_ENABLE 1 @@ -168,6 +170,15 @@ static void debug_ping(evutil_socket_t fd, short what, void *arg) } #endif /* DEBUG_PING_SELF */ +static void configure_signals(void) +{ + sigset_t signals; + /* ignore SIGPIPE */ + sigemptyset(&signals); + sigaddset(&signals, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &signals, NULL); +} + int main(int argc, char *argv[]) { TALLOC_CTX *main_ctx=NULL; @@ -176,14 +187,16 @@ int main(int argc, char *argv[]) struct cmdline_args opts; struct event_base *ev_base; struct tr_socket_event tids_ev; - TR_TRPS_EVENTS *trps_ev; struct event *cfgwatch_ev; + #if DEBUG_PING_SELF struct event *debug_ping_ev; struct timeval notime={0, 0}; struct thingy thingy={NULL}; #endif /* DEBUG_PING_SELF */ + configure_signals(); + /* we're going to be multithreaded, so disable null context tracking */ talloc_set_abort_fn(tr_abort); talloc_disable_null_tracking(); @@ -232,7 +245,7 @@ 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); + tr->cfgwatch->update_cookie=(void *)tr; if (0 != tr_read_and_apply_config(tr->cfgwatch)) { tr_crit("Error reading configuration, exiting."); return 1; @@ -245,11 +258,6 @@ int main(int argc, char *argv[]) return 1; } - /* install configuration file watching events */ - tr->cfgwatch->poll_interval=(struct timeval) {1,0}; /* set poll interval in {sec, usec} */ - tr->cfgwatch->settling_time=(struct timeval) {5,0}; /* delay for changes to settle before updating */ - /* TODO: pull these settings out of the configuration files */ - /* already set config_dir, fstat_list and n_files earlier */ if (0 != tr_cfgwatch_event_init(ev_base, tr->cfgwatch, &cfgwatch_ev)) { tr_crit("Error initializing configuration file watcher."); @@ -268,11 +276,7 @@ int main(int argc, char *argv[]) } /* install TRP handler events */ - trps_ev=tr_trps_events_new(main_ctx); - if (0 != tr_trps_event_init(ev_base, - tr->trps, - tr->cfg_mgr, - trps_ev)) { + if (TRP_SUCCESS != tr_trps_event_init(ev_base, tr)) { tr_crit("Error initializing Trust Path Query Server instance."); return 1; } @@ -305,6 +309,19 @@ int main(int argc, char *argv[]) return 1; } + hc_peer=trp_peer_new(main_ctx); /* will later be stolen by ptable context */ + if (hc_peer==NULL) { + tr_crit("Unable to allocate new peer. Aborting."); + return 1; + } + trp_peer_set_server(hc_peer, "epsilon.vmnet"); + trp_peer_set_gssname(hc_peer, tr_new_name("trpc@apc.painless-security.com")); + trp_peer_set_port(hc_peer, 10002); /* not really used */ + if (TRP_SUCCESS != trps_add_peer(tr->trps, hc_peer)) { + tr_crit("Unable to add peer."); + return 1; + } + s=trp_ptable_to_str(main_ctx, tr->trps->ptable, NULL, NULL); tr_debug("Peer Table:\n%s\n", s); talloc_free(s); diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 91b9dd7..ed07918 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -1,3 +1,4 @@ +#include /* TODO: remove this --jlr */ #include #include #include @@ -9,6 +10,7 @@ #include #include +#include #include #include #include @@ -48,7 +50,7 @@ static TRP_RC tr_trps_msg_handler(TRPS_INSTANCE *trps, /* n.b., conn is available here, but do not hold onto the reference * because it may be cleaned up if the originating connection goes * down before the message is processed */ - mq_msg=tr_mq_msg_new(tmp_ctx, "tr_msg"); + mq_msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_MSG_RECEIVED); if (mq_msg==NULL) { return TRP_NOMEM; } @@ -89,7 +91,7 @@ struct trps_thread_data { TRP_CONNECTION *conn; TRPS_INSTANCE *trps; }; -/* thread to handle GSS connections to peers */ +/* thread to handle GSS connections from peers */ static void *tr_trps_thread(void *arg) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); @@ -141,9 +143,8 @@ static void tr_trps_event_cb(int listener, short event, void *arg) } thread_data->conn=conn; thread_data->trps=trps; - pthread_create(trp_connection_get_thread(conn), NULL, tr_trps_thread, thread_data); - pthread_detach(*(trp_connection_get_thread(conn))); /* we will not rejoin the thread */ trps_add_connection(trps, conn); /* remember the connection */ + pthread_create(trp_connection_get_thread(conn), NULL, tr_trps_thread, thread_data); } } talloc_free(tmp_ctx); @@ -153,30 +154,20 @@ 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 */ + tr_debug("tr_trps_cleanup_conn: freeing %p", conn); +/* pthread_join(*trp_connection_get_thread(conn), NULL); -- removed while debugging, put back!!! --jlr */ trps_remove_connection(trps, conn); + talloc_report_full(conn, stderr); 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, TR_MQMSG_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 */ - + tr_debug("tr_trps_cleanup_conn: deleted connection"); } -#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 */ + pthread_join(*trp_connection_get_thread(trpc_get_conn(trpc)), NULL); trps_remove_trpc(trps, trpc); trpc_free(trpc); - tr_debug("Deleted connection"); + tr_debug("tr_trps_cleanup_trpc: deleted connection"); } static void tr_trps_print_route_table(TRPS_INSTANCE *trps, FILE *f) @@ -196,6 +187,7 @@ static void tr_trps_process_mq(int socket, short event, void *arg) TR_MQ_MSG *msg=NULL; const char *s=NULL; + talloc_report_full(trps->mq, stderr); msg=trps_mq_pop(trps); while (msg!=NULL) { s=tr_mq_msg_get_message(msg); @@ -211,7 +203,7 @@ static void tr_trps_process_mq(int socket, short event, void *arg) TRPC_INSTANCE)); } - else if (0==strcmp(s, "tr_msg")) { + else if (0==strcmp(s, TR_MQMSG_MSG_RECEIVED)) { if (trps_handle_tr_msg(trps, tr_mq_msg_get_payload(msg))!=TRP_SUCCESS) tr_notice("tr_trps_process_mq: error handling message."); else { @@ -245,6 +237,7 @@ static void tr_trps_sweep(int listener, short event, void *arg) tr_debug("tr_trps_sweep: sweeping routes."); trps_sweep_routes(trps); + tr_trps_print_route_table(trps, stderr); /* schedule the event to run again */ event_add(ev, &(trps->sweep_interval)); } @@ -274,7 +267,7 @@ static int tr_trps_events_destructor(void *obj) event_free(ev->sweep_ev); return 0; } -TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx) +static TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx) { TR_TRPS_EVENTS *ev=talloc(mem_ctx, TR_TRPS_EVENTS); if (ev!=NULL) { @@ -286,18 +279,21 @@ TR_TRPS_EVENTS *tr_trps_events_new(TALLOC_CTX *mem_ctx) if (ev->listen_ev==NULL) { talloc_free(ev); ev=NULL; + } else { + talloc_set_destructor((void *)ev, tr_trps_events_destructor); } - talloc_set_destructor((void *)ev, tr_trps_events_destructor); } return ev; } +static void tr_trps_events_free(TR_TRPS_EVENTS *ev) +{ + talloc_free(ev); +} + /* Configure the trps instance and set up its event handler. * Fills in trps_ev, which should be allocated by caller. */ -TRP_RC tr_trps_event_init(struct event_base *base, - TRPS_INSTANCE *trps, - TR_CFG_MGR *cfg_mgr, - TR_TRPS_EVENTS *trps_ev) +TRP_RC tr_trps_event_init(struct event_base *base, TR_INSTANCE *tr) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); struct tr_socket_event *listen_ev=NULL; @@ -305,39 +301,49 @@ TRP_RC tr_trps_event_init(struct event_base *base, struct tr_trps_event_cookie *connection_cookie=NULL; struct tr_trps_event_cookie *update_cookie=NULL; struct tr_trps_event_cookie *sweep_cookie=NULL; + struct timeval zero_time={0,0}; TRP_RC retval=TRP_ERROR; - if (trps_ev == NULL) { - tr_debug("tr_trps_event_init: Null trps_ev."); - retval=TRP_BADARG; + if (tr->events != NULL) { + tr_notice("tr_trps_event_init: tr->events was not null. Freeing before reallocating.."); + tr_trps_events_free(tr->events); + } + + tr->events=tr_trps_events_new(tmp_ctx); + if (tr->events == NULL) { + tr_debug("tr_trps_event_init: unable to allocate event handles."); + retval=TRP_NOMEM; goto cleanup; } /* get convenient handles */ - listen_ev=trps_ev->listen_ev; + listen_ev=tr->events->listen_ev; - /* Create the cookie for callbacks. It is part of the trps context, so it will + /* Create the cookie for callbacks. It will end up part of the trps context, so it will * be cleaned up when trps is freed by talloc_free. */ - trps_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + trps_cookie=talloc(tr->events, struct tr_trps_event_cookie); if (trps_cookie == NULL) { tr_debug("tr_trps_event_init: Unable to allocate trps_cookie."); retval=TRP_NOMEM; + tr_trps_events_free(tr->events); + tr->events=NULL; goto cleanup; } - trps_cookie->trps=trps; - trps_cookie->cfg_mgr=cfg_mgr; - talloc_steal(trps, trps_cookie); + trps_cookie->trps=tr->trps; + trps_cookie->cfg_mgr=tr->cfg_mgr; /* get a trps listener */ - listen_ev->sock_fd=trps_get_listener(trps, + listen_ev->sock_fd=trps_get_listener(tr->trps, tr_trps_msg_handler, tr_trps_gss_handler, - cfg_mgr->active->internal->hostname, - cfg_mgr->active->internal->trps_port, + tr->cfg_mgr->active->internal->hostname, + tr->cfg_mgr->active->internal->trps_port, (void *)trps_cookie); if (listen_ev->sock_fd < 0) { tr_crit("Error opening TRP server socket."); retval=TRP_ERROR; + tr_trps_events_free(tr->events); + tr->events=NULL; goto cleanup; } trps_cookie->ev=listen_ev->ev; /* in case it needs to frob the event */ @@ -347,60 +353,65 @@ TRP_RC tr_trps_event_init(struct event_base *base, listen_ev->sock_fd, EV_READ|EV_PERSIST, tr_trps_event_cb, - (void *)trps); + (void *)(tr->trps)); event_add(listen_ev->ev, NULL); /* now set up message queue processing event, only triggered by * tr_trps_mq_cb() */ - trps_ev->mq_ev=event_new(base, - 0, - EV_PERSIST, - tr_trps_process_mq, - (void *)trps); - tr_mq_set_notify_cb(trps->mq, tr_trps_mq_cb, trps_ev->mq_ev); + tr->events->mq_ev=event_new(base, + 0, + EV_PERSIST, + tr_trps_process_mq, + (void *)(tr->trps)); + tr_mq_set_notify_cb(tr->trps->mq, tr_trps_mq_cb, tr->events->mq_ev); /* now set up the peer connection timer event */ - connection_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + connection_cookie=talloc(tr->events, struct tr_trps_event_cookie); if (connection_cookie == NULL) { tr_debug("tr_trps_event_init: Unable to allocate connection_cookie."); retval=TRP_NOMEM; + tr_trps_events_free(tr->events); + tr->events=NULL; 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)); + connection_cookie->trps=tr->trps; + connection_cookie->cfg_mgr=tr->cfg_mgr; + tr->events->connect_ev=event_new(base, -1, EV_TIMEOUT, tr_connection_update, (void *)connection_cookie); + connection_cookie->ev=tr->events->connect_ev; /* in case it needs to frob the event */ + /* The first time, do this immediately. Thereafter, it will retrigger every trps->connect_interval */ + event_add(tr->events->connect_ev, &zero_time); /* now set up the route update timer event */ - update_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + update_cookie=talloc(tr->events, struct tr_trps_event_cookie); if (update_cookie == NULL) { tr_debug("tr_trps_event_init: Unable to allocate update_cookie."); retval=TRP_NOMEM; + tr_trps_events_free(tr->events); + tr->events=NULL; 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)); + update_cookie->trps=tr->trps; + update_cookie->cfg_mgr=tr->cfg_mgr; + tr->events->update_ev=event_new(base, -1, EV_TIMEOUT, tr_trps_update, (void *)update_cookie); + update_cookie->ev=tr->events->update_ev; /* in case it needs to frob the event */ + event_add(tr->events->update_ev, &(tr->trps->update_interval)); /* now set up the route table sweep timer event */ - sweep_cookie=talloc(tmp_ctx, struct tr_trps_event_cookie); + sweep_cookie=talloc(tr->events, struct tr_trps_event_cookie); if (sweep_cookie == NULL) { tr_debug("tr_trps_event_init: Unable to allocate sweep_cookie."); retval=TRP_NOMEM; + tr_trps_events_free(tr->events); + tr->events=NULL; 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)); + sweep_cookie->trps=tr->trps; + sweep_cookie->cfg_mgr=tr->cfg_mgr; + tr->events->sweep_ev=event_new(base, -1, EV_TIMEOUT, tr_trps_sweep, (void *)sweep_cookie); + sweep_cookie->ev=tr->events->sweep_ev; /* in case it needs to frob the event */ + event_add(tr->events->sweep_ev, &(tr->trps->sweep_interval)); + talloc_steal(tr, tr->events); retval=TRP_SUCCESS; cleanup: @@ -456,10 +467,13 @@ static void *tr_trpc_thread(void *arg) tr_mq_unlock(trpc->mq); rc=trpc_connect(trpc); +/* talloc_report_full(trpc, stderr);*/ if (rc!=TRP_SUCCESS) { - tr_notice("tr_trpc_thread: failed to initiate connection to %s:%d.", - trpc_get_server(trpc), - trpc_get_port(trpc)); + /* was tr_notice --jlr */ + fprintf(stderr, "tr_trpc_thread: failed to initiate connection to %s:%d.", + trpc_get_server(trpc), + trpc_get_port(trpc)); + fflush(stderr); } else { tr_debug("tr_trpc_thread: connected to peer %s", trpc->conn->peer->buf); while (1) { @@ -501,6 +515,7 @@ static void *tr_trpc_thread(void *arg) } } + tr_debug("tr_trpc_thread: exiting."); msg=tr_mq_msg_new(tmp_ctx, TR_MQMSG_TRPC_DISCONNECTED); tr_mq_msg_set_payload(msg, (void *)trpc, NULL); /* do not pass a free routine */ if (msg==NULL) @@ -513,15 +528,15 @@ static void *tr_trpc_thread(void *arg) } /* convert an IDP realm into routing table entries. Outputs number in *n_routes */ -static TRP_RENTRY **tr_make_local_routes(TALLOC_CTX *mem_ctx, +static TRP_ROUTE **tr_make_local_routes(TALLOC_CTX *mem_ctx, TR_IDP_REALM *realm, char *trust_router, size_t *n_routes) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_APC *apc=NULL; - TRP_RENTRY *new_entry=NULL; - TRP_RENTRY **entries=NULL; + TRP_ROUTE *new_entry=NULL; + TRP_ROUTE **entries=NULL; size_t n_apcs=0, ii=0; *n_routes=0; @@ -532,22 +547,21 @@ static TRP_RENTRY **tr_make_local_routes(TALLOC_CTX *mem_ctx, /* count apcs */ for (apc=realm->apcs, n_apcs=0; apc!=NULL; apc=apc->next,n_apcs++) {} - entries=talloc_array(tmp_ctx, TRP_RENTRY *, n_apcs); + entries=talloc_array(tmp_ctx, TRP_ROUTE *, n_apcs); for (apc=realm->apcs,ii=0; apc!=NULL; apc=apc->next, ii++) { - new_entry=trp_rentry_new(entries); + new_entry=trp_route_new(entries); if (new_entry==NULL) { tr_crit("tr_make_local_routes: unable to allocate entry."); talloc_free(entries); goto cleanup; } - trp_rentry_set_apc(new_entry, tr_dup_name(apc->id)); - trp_rentry_set_realm(new_entry, tr_dup_name(realm->realm_id)); - trp_rentry_set_peer(new_entry, tr_new_name("")); /* no peer, it's us */ - trp_rentry_set_metric(new_entry, 0); - trp_rentry_set_trust_router(new_entry, tr_new_name(trust_router)); - trp_rentry_set_next_hop(new_entry, tr_new_name("")); - /* we do not set selected (tbd later) or expiry/interval (not needed for - * local routes) */ + trp_route_set_apc(new_entry, tr_dup_name(apc->id)); + trp_route_set_realm(new_entry, tr_dup_name(realm->realm_id)); + trp_route_set_peer(new_entry, tr_new_name("")); /* no peer, it's us */ + trp_route_set_metric(new_entry, 0); + trp_route_set_trust_router(new_entry, tr_new_name(trust_router)); + trp_route_set_next_hop(new_entry, tr_new_name("")); + trp_route_set_local(new_entry, 1); entries[ii]=new_entry; } @@ -566,8 +580,6 @@ struct tr_trpc_status_change_cookie { static void tr_trpc_status_change(TRP_CONNECTION *conn, void *cookie) { struct tr_trpc_status_change_cookie *cook=talloc_get_type_abort(cookie, struct tr_trpc_status_change_cookie); - /*TRPS_INSTANCE *trps=cook->trps;*/ - /* TRPC_INSTANCE *trpc=cook->trpc;*/ TRP_PEER *peer=cook->peer; TR_NAME *gssname=trp_peer_get_gssname(peer); @@ -578,18 +590,20 @@ static void tr_trpc_status_change(TRP_CONNECTION *conn, void *cookie) } /* starts a trpc thread to connect to server:port */ -TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer) +TRP_RC tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TRPC_INSTANCE *trpc=NULL; TRP_CONNECTION *conn=NULL; struct trpc_thread_data *thread_data=NULL; struct tr_trpc_status_change_cookie *status_change_cookie=NULL; + TRP_RC rc=TRP_ERROR; tr_debug("tr_trpc_initiate entered"); trpc=trpc_new(tmp_ctx); if (trpc==NULL) { tr_crit("tr_trpc_initiate: could not allocate TRPC_INSTANCE."); + rc=TRP_NOMEM; goto cleanup; } tr_debug("tr_trpc_initiate: allocated trpc"); @@ -597,12 +611,14 @@ TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer) conn=trp_connection_new(trpc); if (conn==NULL) { tr_crit("tr_trpc_initiate: could not allocate TRP_CONNECTION."); + rc=TRP_NOMEM; goto cleanup; } status_change_cookie=talloc(conn, struct tr_trpc_status_change_cookie); if (status_change_cookie==NULL) { tr_crit("tr_trpc_initiate: could not allocate connection status cookie."); + rc=TRP_NOMEM; goto cleanup; } status_change_cookie->trps=trps; @@ -622,20 +638,22 @@ TRPC_INSTANCE *tr_trpc_initiate(TRPS_INSTANCE *trps, TRP_PEER *peer) thread_data=talloc(trpc, struct trpc_thread_data); if (thread_data==NULL) { tr_crit("tr_trpc_initiate: could not allocate struct trpc_thread_data."); + rc=TRP_NOMEM; goto cleanup; } thread_data->trpc=trpc; thread_data->trps=trps; + trps_add_trpc(trps, trpc); /* must add before starting thread */ pthread_create(trp_connection_get_thread(conn), NULL, tr_trpc_thread, thread_data); - pthread_detach(*(trp_connection_get_thread(conn))); /* we will not rejoin the thread */ tr_debug("tr_trpc_initiate: started trpc thread"); - trps_add_trpc(trps, trpc); + rc=TRP_SUCCESS; cleanup: + talloc_report_full(tmp_ctx, stderr); talloc_free(tmp_ctx); - return trpc; + return rc; } /* Add local routes to the route table. */ @@ -643,7 +661,7 @@ TRP_RC tr_add_local_routes(TRPS_INSTANCE *trps, TR_CFG *cfg) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_IDP_REALM *cur=NULL; - TRP_RENTRY **local_routes=NULL; + TRP_ROUTE **local_routes=NULL; size_t n_routes=0; size_t ii=0; char *trust_router_name=talloc_asprintf(tmp_ctx, "%s:%d", cfg->internal->hostname, cfg->internal->trps_port); @@ -678,7 +696,6 @@ 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; @@ -698,8 +715,7 @@ TRP_RC tr_connect_to_peers(TRPS_INSTANCE *trps) /* 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) { + if (tr_trpc_initiate(trps, peer)!=TRP_SUCCESS) { tr_err("tr_connect_to_peers: unable to initiate TRP connection to %s:%u.", trp_peer_get_server(peer), trp_peer_get_port(peer)); @@ -720,7 +736,15 @@ cleanup: * 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); + TR_INSTANCE *tr=talloc_get_type_abort(cookie, TR_INSTANCE); + TRPS_INSTANCE *trps=tr->trps; + + tr->cfgwatch->poll_interval.tv_sec=new_cfg->internal->cfg_poll_interval; + tr->cfgwatch->poll_interval.tv_usec=0; + + tr->cfgwatch->settling_time.tv_sec=new_cfg->internal->cfg_settling_time; + tr->cfgwatch->settling_time.tv_usec=0; + 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/tr/trpc_main.c b/tr/trpc_main.c index e9e0de6..f04b4dd 100644 --- a/tr/trpc_main.c +++ b/tr/trpc_main.c @@ -41,7 +41,6 @@ #include #include #include -#include /* command-line option setup */ @@ -124,9 +123,7 @@ int main (int argc, { TALLOC_CTX *main_ctx=talloc_new(NULL); TRPC_INSTANCE *trpc=NULL; - int conn = 0; - int rc; - gss_ctx_id_t gssctx; + TRP_CONNECTION *conn=NULL; struct cmdline_args opts; /* parse the command line*/ @@ -137,7 +134,6 @@ int main (int argc, opts.repeat=1; argp_parse(&argp, argc, argv, 0, 0, &opts); - /* TBD -- validity checking, dealing with quotes, etc. */ /* Use standalone logging */ tr_log_open(); @@ -149,25 +145,27 @@ int main (int argc, printf("TRPC Client:\nServer = %s, port = %i\n", opts.server, opts.port); - /* Create a TRP client instance & the client DH */ - trpc = trpc_new(main_ctx); - if (NULL == (trpc->client_dh = tr_create_dh_params(NULL, 0))) { - printf("Error creating client DH params.\n"); + conn=trp_connection_new(trpc); + if (conn==NULL) { + printf("Could not allocate TRP_CONNECTION.\n"); return 1; } - + trpc = trpc_new(main_ctx); + trpc_set_server(trpc, opts.server); + trpc_set_port(trpc, opts.port); + trpc_set_conn(trpc, conn); /* Set-up TRP connection */ - if (-1 == (conn = trpc_open_connection(trpc, opts.server, opts.port, &gssctx))) { + if (TRP_SUCCESS != trpc_connect(trpc)) { /* Handle error */ - printf("Error in trpc_open_connection.\n"); + printf("Error in trpc_connect.\n"); return 1; - }; + } /* Send a TRP message */ while ((opts.repeat==-1) || (opts.repeat-->0)) { - if (0 > (rc = trpc_send_msg(trpc, conn, gssctx, opts.msg, NULL, NULL))) { + if (TRP_SUCCESS != trpc_send_msg(trpc, opts.msg)) { /* Handle error */ - printf("Error in trpc_send_request, rc = %d.\n", rc); + printf("Error in trpc_send_request."); return 1; } usleep(1000000); diff --git a/trp/trp_conn.c b/trp/trp_conn.c index 5d38de4..99d8593 100644 --- a/trp/trp_conn.c +++ b/trp/trp_conn.c @@ -205,7 +205,7 @@ static void trp_connection_mutex_init(TRP_CONNECTION *conn) static int trp_connection_destructor(void *object) { TRP_CONNECTION *conn=talloc_get_type_abort(object, TRP_CONNECTION); /* aborts on wrong type */ - if ((trp_connection_get_status(conn)!=TRP_CONNECTION_DOWN) + if ((trp_connection_get_status(conn)!=TRP_CONNECTION_CLOSED) && (trp_connection_get_fd(conn)!=-1)) close(trp_connection_get_fd(conn)); if (conn->peer!=NULL) @@ -230,7 +230,7 @@ TRP_CONNECTION *trp_connection_new(TALLOC_CTX *mem_ctx) new_conn->peer=NULL; /* no true set function for this */ new_conn->status_change_cb=NULL; new_conn->status_change_cookie=NULL; - new_conn->status=TRP_CONNECTION_DOWN; /* set directly in the constructor */ + new_conn->status=TRP_CONNECTION_CLOSED; thread=talloc(new_conn, pthread_t); if (thread==NULL) { @@ -271,13 +271,17 @@ int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void gss_ctx_id_t *gssctx=trp_connection_get_gssctx(conn); nameBuffer.length = trp_connection_get_gssname(conn)->len; - nameBuffer.value = trp_connection_get_gssname(conn)->buf; + nameBuffer.value = tr_name_strdup(trp_connection_get_gssname(conn)); tr_debug("trp_connection_auth: beginning passive authentication"); + if (trp_connection_get_status(conn)!=TRP_CONNECTION_AUTHORIZING) + tr_warning("trp_connection_auth: warning: connection was not in TRP_CONNECTION_AUTHORIZING state."); + rc = gsscon_passive_authenticate(trp_connection_get_fd(conn), nameBuffer, gssctx, auth_callback, callback_data); gss_release_buffer(NULL, &nameBuffer); if (rc!=0) { tr_debug("trp_connection_auth: Error from gsscon_passive_authenticate(), rc = 0x%08X.", rc); + trp_connection_set_status(conn, TRP_CONNECTION_DOWN); return -1; } @@ -285,6 +289,7 @@ int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void if (rc = gsscon_authorize(*gssctx, &auth, &autherr)) { tr_debug("trp_connection_auth: Error from gsscon_authorize, rc = %d, autherr = %d.", rc, autherr); + trp_connection_set_status(conn, TRP_CONNECTION_DOWN); return -1; } @@ -314,6 +319,7 @@ TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME * conn=trp_connection_new(mem_ctx); trp_connection_set_fd(conn, conn_fd); trp_connection_set_gssname(conn, gssname); + trp_connection_set_status(conn, TRP_CONNECTION_AUTHORIZING); return conn; } @@ -344,7 +350,6 @@ TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, unsigned int trp_connection_get_gssctx(conn)); if (err) { tr_debug("trp_connection_initiate: connection failed."); - talloc_free(conn); return TRP_ERROR; } else { tr_debug("trp_connection_initiate: connected."); diff --git a/trp/trp_ptable.c b/trp/trp_ptable.c index afee7ef..557bc0d 100644 --- a/trp/trp_ptable.c +++ b/trp/trp_ptable.c @@ -21,7 +21,7 @@ TRP_PEER *trp_peer_new(TALLOC_CTX *memctx) peer->server=NULL; peer->gssname=NULL; peer->port=0; - peer->linkcost=TRP_METRIC_INFINITY; + peer->linkcost=TRP_LINKCOST_DEFAULT; peer->last_conn_attempt=(struct timespec){0,0}; talloc_set_destructor((void *)peer, trp_peer_destructor); } diff --git a/trp/trp_rtable.c b/trp/trp_rtable.c index 7a519bb..69f845c 100644 --- a/trp/trp_rtable.c +++ b/trp/trp_rtable.c @@ -11,9 +11,9 @@ /* Note: be careful mixing talloc with glib. */ -static int trp_rentry_destructor(void *obj) +static int trp_route_destructor(void *obj) { - TRP_RENTRY *entry=talloc_get_type_abort(obj, TRP_RENTRY); + TRP_ROUTE *entry=talloc_get_type_abort(obj, TRP_ROUTE); if (entry->apc!=NULL) tr_free_name(entry->apc); if (entry->realm!=NULL) @@ -27,9 +27,9 @@ static int trp_rentry_destructor(void *obj) return 0; } -TRP_RENTRY *trp_rentry_new(TALLOC_CTX *mem_ctx) +TRP_ROUTE *trp_route_new(TALLOC_CTX *mem_ctx) { - TRP_RENTRY *entry=talloc(mem_ctx, TRP_RENTRY); + TRP_ROUTE *entry=talloc(mem_ctx, TRP_ROUTE); if (entry!=NULL) { entry->apc=NULL; entry->realm=NULL; @@ -43,140 +43,163 @@ TRP_RENTRY *trp_rentry_new(TALLOC_CTX *mem_ctx) talloc_free(entry); return NULL; } - talloc_set_destructor((void *)entry, trp_rentry_destructor); + *(entry->expiry)=(struct timespec){0,0}; + entry->local=0; + entry->triggered=0; + talloc_set_destructor((void *)entry, trp_route_destructor); } return entry; } -void trp_rentry_free(TRP_RENTRY *entry) +void trp_route_free(TRP_ROUTE *entry) { if (entry!=NULL) talloc_free(entry); } -void trp_rentry_set_apc(TRP_RENTRY *entry, TR_NAME *apc) +void trp_route_set_apc(TRP_ROUTE *entry, TR_NAME *apc) { + if (entry->apc!=NULL) + tr_free_name(entry->apc); entry->apc=apc; } -TR_NAME *trp_rentry_get_apc(TRP_RENTRY *entry) +TR_NAME *trp_route_get_apc(TRP_ROUTE *entry) { return entry->apc; } -TR_NAME *trp_rentry_dup_apc(TRP_RENTRY *entry) +TR_NAME *trp_route_dup_apc(TRP_ROUTE *entry) { - return tr_dup_name(trp_rentry_get_apc(entry)); + return tr_dup_name(trp_route_get_apc(entry)); } -void trp_rentry_set_realm(TRP_RENTRY *entry, TR_NAME *realm) +void trp_route_set_realm(TRP_ROUTE *entry, TR_NAME *realm) { + if (entry->realm!=NULL) + tr_free_name(entry->realm); entry->realm=realm; } -TR_NAME *trp_rentry_get_realm(TRP_RENTRY *entry) +TR_NAME *trp_route_get_realm(TRP_ROUTE *entry) { return entry->realm; } -TR_NAME *trp_rentry_dup_realm(TRP_RENTRY *entry) +TR_NAME *trp_route_dup_realm(TRP_ROUTE *entry) { - return tr_dup_name(trp_rentry_get_realm(entry)); + return tr_dup_name(trp_route_get_realm(entry)); } -void trp_rentry_set_trust_router(TRP_RENTRY *entry, TR_NAME *tr) +void trp_route_set_trust_router(TRP_ROUTE *entry, TR_NAME *tr) { + if (entry->trust_router!=NULL) + tr_free_name(entry->trust_router); entry->trust_router=tr; } -TR_NAME *trp_rentry_get_trust_router(TRP_RENTRY *entry) +TR_NAME *trp_route_get_trust_router(TRP_ROUTE *entry) { return entry->trust_router; } -TR_NAME *trp_rentry_dup_trust_router(TRP_RENTRY *entry) +TR_NAME *trp_route_dup_trust_router(TRP_ROUTE *entry) { - return tr_dup_name(trp_rentry_get_trust_router(entry)); + return tr_dup_name(trp_route_get_trust_router(entry)); } -void trp_rentry_set_peer(TRP_RENTRY *entry, TR_NAME *peer) +void trp_route_set_peer(TRP_ROUTE *entry, TR_NAME *peer) { + if (entry->peer!=NULL) + tr_free_name(entry->peer); entry->peer=peer; } -TR_NAME *trp_rentry_get_peer(TRP_RENTRY *entry) +TR_NAME *trp_route_get_peer(TRP_ROUTE *entry) { return entry->peer; } -TR_NAME *trp_rentry_dup_peer(TRP_RENTRY *entry) +TR_NAME *trp_route_dup_peer(TRP_ROUTE *entry) { - return tr_dup_name(trp_rentry_get_peer(entry)); + return tr_dup_name(trp_route_get_peer(entry)); } -void trp_rentry_set_metric(TRP_RENTRY *entry, unsigned int metric) +void trp_route_set_metric(TRP_ROUTE *entry, unsigned int metric) { entry->metric=metric; } -unsigned int trp_rentry_get_metric(TRP_RENTRY *entry) +unsigned int trp_route_get_metric(TRP_ROUTE *entry) { return entry->metric; } -void trp_rentry_set_next_hop(TRP_RENTRY *entry, TR_NAME *next_hop) +void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop) { + if (entry->next_hop!=NULL) + tr_free_name(entry->next_hop); entry->next_hop=next_hop; } -TR_NAME *trp_rentry_get_next_hop(TRP_RENTRY *entry) +TR_NAME *trp_route_get_next_hop(TRP_ROUTE *entry) { return entry->next_hop; } -TR_NAME *trp_rentry_dup_next_hop(TRP_RENTRY *entry) +TR_NAME *trp_route_dup_next_hop(TRP_ROUTE *entry) { - return tr_dup_name(trp_rentry_get_next_hop(entry)); + return tr_dup_name(trp_route_get_next_hop(entry)); } -void trp_rentry_set_selected(TRP_RENTRY *entry, int sel) +void trp_route_set_selected(TRP_ROUTE *entry, int sel) { entry->selected=sel; } -int trp_rentry_get_selected(TRP_RENTRY *entry) +int trp_route_is_selected(TRP_ROUTE *entry) { return entry->selected; } -void trp_rentry_set_interval(TRP_RENTRY *entry, int interval) +void trp_route_set_interval(TRP_ROUTE *entry, int interval) { entry->interval=interval; } -int trp_rentry_get_interval(TRP_RENTRY *entry) +int trp_route_get_interval(TRP_ROUTE *entry) { return entry->interval; } /* copies incoming value, does not assume responsibility for freeing */ -void trp_rentry_set_expiry(TRP_RENTRY *entry, struct timespec *exp) +void trp_route_set_expiry(TRP_ROUTE *entry, struct timespec *exp) { entry->expiry->tv_sec=exp->tv_sec; entry->expiry->tv_nsec=exp->tv_nsec; } -struct timespec *trp_rentry_get_expiry(TRP_RENTRY *entry) +struct timespec *trp_route_get_expiry(TRP_ROUTE *entry) { return entry->expiry; } -void trp_rentry_set_triggered(TRP_RENTRY *entry, int trig) +void trp_route_set_local(TRP_ROUTE *entry, int local) +{ + entry->local=local; +} + +int trp_route_is_local(TRP_ROUTE *entry) +{ + return entry->local; +} + +void trp_route_set_triggered(TRP_ROUTE *entry, int trig) { entry->triggered=trig; } -int trp_rentry_get_triggered(TRP_RENTRY *entry) +int trp_route_is_triggered(TRP_ROUTE *entry) { return entry->triggered; } @@ -186,6 +209,8 @@ int trp_rentry_get_triggered(TRP_RENTRY *entry) static gchar *tr_name_to_g_str(const TR_NAME *n) { gchar *s=g_strndup(n->buf, n->len); + if (s==NULL) + tr_debug("tr_name_to_g_str: allocation failure."); return s; } @@ -220,7 +245,7 @@ static void trp_rtable_destroy_table(gpointer data) static void trp_rtable_destroy_rentry(gpointer data) { - trp_rentry_free(data); + trp_route_free(data); } static void trp_rtable_destroy_tr_name(gpointer data) @@ -257,7 +282,7 @@ static GHashTable *trp_rtbl_get_or_add_table(GHashTable *tbl, TR_NAME *key, GDes return val_tbl; } -void trp_rtable_add(TRP_RTABLE *rtbl, TRP_RENTRY *entry) +void trp_rtable_add(TRP_RTABLE *rtbl, TRP_ROUTE *entry) { GHashTable *apc_tbl=NULL; GHashTable *realm_tbl=NULL; @@ -270,7 +295,7 @@ void trp_rtable_add(TRP_RTABLE *rtbl, TRP_RENTRY *entry) } /* note: the entry pointer passed in is invalid after calling this because the entry is freed */ -void trp_rtable_remove(TRP_RTABLE *rtbl, TRP_RENTRY *entry) +void trp_rtable_remove(TRP_RTABLE *rtbl, TRP_ROUTE *entry) { GHashTable *apc_tbl=NULL; GHashTable *realm_tbl=NULL; @@ -361,15 +386,15 @@ size_t trp_rtable_realm_size(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm) realm)); } -/* Returns an array of pointers to TRP_RENTRY, length of array in n_out. +/* Returns an array of pointers to TRP_ROUTE, length of array in n_out. * Caller must free the array (in the talloc NULL context), but must * not free its contents. */ -TRP_RENTRY **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out) +TRP_ROUTE **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out) { - TRP_RENTRY **ret=NULL; + TRP_ROUTE **ret=NULL; TR_NAME **apc=NULL; size_t n_apc=0; - TRP_RENTRY **apc_entries=NULL; + TRP_ROUTE **apc_entries=NULL; size_t n_entries=0; size_t ii_ret=0; @@ -377,7 +402,7 @@ TRP_RENTRY **trp_rtable_get_entries(TRP_RTABLE *rtbl, size_t *n_out) if (*n_out==0) return NULL; - ret=talloc_array(NULL, TRP_RENTRY *, *n_out); + ret=talloc_array(NULL, TRP_ROUTE *, *n_out); if (ret==NULL) { tr_crit("trp_rtable_get_entries: unable to allocate return array."); *n_out=0; @@ -461,21 +486,21 @@ TR_NAME **trp_rtable_get_apc_realms(TRP_RTABLE *rtbl, TR_NAME *apc, size_t *n_ou /* Get all entries in an apc. Returns an array of pointers in NULL talloc context. * Caller must free this list with talloc_free, but must not free the entries in the * list.. */ -TRP_RENTRY **trp_rtable_get_apc_entries(TRP_RTABLE *rtbl, TR_NAME *apc, size_t *n_out) +TRP_ROUTE **trp_rtable_get_apc_entries(TRP_RTABLE *rtbl, TR_NAME *apc, size_t *n_out) { size_t ii=0, jj=0; TR_NAME **realm=NULL; size_t n_realms=0; - TRP_RENTRY **realm_entries=NULL; + TRP_ROUTE **realm_entries=NULL; size_t n_entries=0; - TRP_RENTRY **ret=NULL; + TRP_ROUTE **ret=NULL; size_t ii_ret=0; *n_out=trp_rtable_apc_size(rtbl, apc); if (*n_out==0) return NULL; - ret=talloc_array(NULL, TRP_RENTRY *, *n_out); + ret=talloc_array(NULL, TRP_ROUTE *, *n_out); if (ret==NULL) { tr_crit("trp_rtable_get_apc_entries: could not allocate return array."); *n_out=0; @@ -505,14 +530,14 @@ TRP_RENTRY **trp_rtable_get_apc_entries(TRP_RTABLE *rtbl, TR_NAME *apc, size_t * /* Get all entries in an apc/realm. Returns an array of pointers in NULL talloc context. * Caller must free this list with talloc_free, but must not free the entries in the * list.. */ -TRP_RENTRY **trp_rtable_get_realm_entries(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, size_t *n_out) +TRP_ROUTE **trp_rtable_get_realm_entries(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, size_t *n_out) { size_t ii=0; - TRP_RENTRY **ret=NULL; + TRP_ROUTE **ret=NULL; TR_NAME **peer=NULL; peer=trp_rtable_get_apc_realm_peers(rtbl, apc, realm, n_out); - ret=talloc_array(NULL, TRP_RENTRY *, *n_out); + ret=talloc_array(NULL, TRP_ROUTE *, *n_out); if (ret==NULL) { tr_crit("trp_rtable_get_realm_entries: could not allocate return array."); talloc_free(peer); @@ -551,7 +576,7 @@ TR_NAME **trp_rtable_get_apc_realm_peers(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME } /* Gets a single entry. Do not free it. */ -TRP_RENTRY *trp_rtable_get_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, TR_NAME *peer) +TRP_ROUTE *trp_rtable_get_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, TR_NAME *peer) { GHashTable *realm_tbl=NULL; @@ -581,16 +606,16 @@ static char *timespec_to_str(struct timespec *ts) return s; } -TRP_RENTRY *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm) +TRP_ROUTE *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm) { size_t n=0; - TRP_RENTRY **entry=trp_rtable_get_realm_entries(rtbl, apc, realm, &n); - TRP_RENTRY *selected=NULL; + TRP_ROUTE **entry=trp_rtable_get_realm_entries(rtbl, apc, realm, &n); + TRP_ROUTE *selected=NULL; if (n==0) return NULL; - while(n-- && !trp_rentry_get_selected(entry[n])) { } + while(n-- && !trp_route_is_selected(entry[n])) { } selected=entry[n]; talloc_free(entry); return selected; @@ -598,7 +623,7 @@ TRP_RENTRY *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAM /* Pretty print a route table entry to a newly allocated string. If sep is NULL, * returns comma+space separated string. */ -char *trp_rentry_to_str(TALLOC_CTX *mem_ctx, TRP_RENTRY *entry, const char *sep) +char *trp_route_to_str(TALLOC_CTX *mem_ctx, TRP_ROUTE *entry, const char *sep) { char *apc=tr_name_strdup(entry->apc); char *realm=tr_name_strdup(entry->realm); @@ -612,7 +637,7 @@ char *trp_rentry_to_str(TALLOC_CTX *mem_ctx, TRP_RENTRY *entry, const char *sep) sep=", "; result=talloc_asprintf(mem_ctx, - "%s%s%s%s%s%s%u%s%s%s%s%s%d%s%s", + "%s%s%s%s%s%s%u%s%s%s%s%s%u%s%u%s%s%s%u", apc, sep, realm, sep, peer, sep, @@ -620,7 +645,9 @@ char *trp_rentry_to_str(TALLOC_CTX *mem_ctx, TRP_RENTRY *entry, const char *sep) trust_router, sep, next_hop, sep, entry->selected, sep, - expiry); + entry->local, sep, + expiry, sep, + entry->triggered); free(apc); free(realm); free(peer); @@ -633,12 +660,12 @@ char *trp_rentry_to_str(TALLOC_CTX *mem_ctx, TRP_RENTRY *entry, const char *sep) void trp_rtable_clear_triggered(TRP_RTABLE *rtbl) { size_t n_entries=0; - TRP_RENTRY **entries=trp_rtable_get_entries(rtbl, &n_entries); + TRP_ROUTE **entries=trp_rtable_get_entries(rtbl, &n_entries); size_t ii=0; if (entries!=NULL) { for (ii=0; iiserver=NULL; trpc->port=0; trpc->conn=NULL; - trpc->dh=NULL; trpc->mq=tr_mq_new(trpc); if (trpc->mq==NULL) { talloc_free(trpc); @@ -135,16 +134,6 @@ void trpc_set_conn(TRPC_INSTANCE *trpc, TRP_CONNECTION *conn) trpc->conn=conn; } -DH *trpc_get_dh(TRPC_INSTANCE *trpc) -{ - return trpc->dh; -} - -void trpc_set_dh(TRPC_INSTANCE *trpc, DH *dh) -{ - trpc->dh=dh; -} - TRP_CONNECTION_STATUS trpc_get_status(TRPC_INSTANCE *trpc) { return trp_connection_get_status(trpc_get_conn(trpc)); diff --git a/trp/trps.c b/trp/trps.c index 03567dd..ec4ada5 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -252,12 +252,12 @@ int trps_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data) #endif /* get the currently selected route if available */ -TRP_RENTRY *trps_get_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer) +TRP_ROUTE *trps_get_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer) { return trp_rtable_get_entry(trps->rtable, comm, realm, peer); } -TRP_RENTRY *trps_get_selected_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm) +TRP_ROUTE *trps_get_selected_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm) { return trp_rtable_get_selected_entry(trps->rtable, comm, realm); } @@ -265,24 +265,25 @@ TRP_RENTRY *trps_get_selected_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME /* copy the result if you want to keep it */ TR_NAME *trps_get_next_hop(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm) { - TRP_RENTRY *route=trps_get_selected_route(trps, comm, realm); + TRP_ROUTE *route=trps_get_selected_route(trps, comm, realm); if (route==NULL) return NULL; - return trp_rentry_get_next_hop(route); + return trp_route_get_next_hop(route); } /* mark a route as retracted */ -static void trps_retract_route(TRPS_INSTANCE *trps, TRP_RENTRY *entry) +static void trps_retract_route(TRPS_INSTANCE *trps, TRP_ROUTE *entry) { - trp_rentry_set_metric(entry, TRP_METRIC_INFINITY); + trp_route_set_metric(entry, TRP_METRIC_INFINITY); + trp_route_set_triggered(entry, 1); } /* is this route retracted? */ -static int trps_route_retracted(TRPS_INSTANCE *trps, TRP_RENTRY *entry) +static int trps_route_retracted(TRPS_INSTANCE *trps, TRP_ROUTE *entry) { - return (trp_metric_is_infinite(trp_rentry_get_metric(entry))); + return (trp_metric_is_infinite(trp_route_get_metric(entry))); } static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MSG **msg) @@ -376,36 +377,35 @@ int trps_get_listener(TRPS_INSTANCE *trps, void trps_handle_connection(TRPS_INSTANCE *trps, TRP_CONNECTION *conn) { - TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_MSG *msg=NULL; TRP_RC rc=TRP_ERROR; /* try to establish a GSS context */ if (0!=trp_connection_auth(conn, trps->auth_handler, trps->cookie)) { tr_notice("tr_trps_conn_thread: failed to authorize connection"); - pthread_exit(NULL); - } - tr_notice("trps_handle_connection: authorized connection"); + trp_connection_close(conn); + } else { + tr_notice("trps_handle_connection: authorized connection"); - /* loop as long as the connection exists */ - while (trp_connection_get_status(conn)==TRP_CONNECTION_UP) { - rc=trps_read_message(trps, conn, &msg); - switch(rc) { - case TRP_SUCCESS: - trps->msg_handler(trps, conn, msg); /* send the TR_MSG off to the callback */ - break; - - case TRP_ERROR: - trp_connection_close(conn); - break; - - default: - tr_debug("trps_handle_connection: trps_read_message failed (%d)", rc); + /* loop as long as the connection exists */ + while (trp_connection_get_status(conn)==TRP_CONNECTION_UP) { + rc=trps_read_message(trps, conn, &msg); + switch(rc) { + case TRP_SUCCESS: + trps->msg_handler(trps, conn, msg); /* send the TR_MSG off to the callback */ + break; + + case TRP_ERROR: + trp_connection_close(conn); + break; + + default: + tr_debug("trps_handle_connection: trps_read_message failed (%d)", rc); + } } - } - tr_debug("trps_handle_connection: connection closed."); - talloc_free(tmp_ctx); + tr_debug("trps_handle_connection: connection closed."); + } } static TRP_RC trps_validate_update(TRPS_INSTANCE *trps, TRP_UPD *upd) @@ -465,10 +465,10 @@ static unsigned int trps_cost(TRPS_INSTANCE *trps, TR_NAME *peer) static unsigned int trps_advertised_metric(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer) { - TRP_RENTRY *entry=trp_rtable_get_entry(trps->rtable, comm, realm, peer); + TRP_ROUTE *entry=trp_rtable_get_entry(trps->rtable, comm, realm, peer); if (entry==NULL) return TRP_METRIC_INFINITY; - return trp_rentry_get_metric(entry) + trps_cost(trps, peer); + return trp_route_get_metric(entry) + trps_cost(trps, peer); } static int trps_check_feasibility(TRPS_INSTANCE *trps, TRP_INFOREC *rec) @@ -524,32 +524,32 @@ static struct timespec *trps_compute_expiry(TRPS_INSTANCE *trps, unsigned int in static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_INFOREC *rec) { - TRP_RENTRY *entry=NULL; + TRP_ROUTE *entry=NULL; entry=trp_rtable_get_entry(trps->rtable, trp_inforec_get_comm(rec), trp_inforec_get_realm(rec), trp_inforec_get_next_hop(rec)); if (entry==NULL) { - entry=trp_rentry_new(NULL); + entry=trp_route_new(NULL); if (entry==NULL) { tr_err("trps_accept_update: unable to allocate new entry."); return TRP_NOMEM; } - trp_rentry_set_apc(entry, tr_dup_name(trp_inforec_get_comm(rec))); - trp_rentry_set_realm(entry, tr_dup_name(trp_inforec_get_realm(rec))); - trp_rentry_set_peer(entry, tr_dup_name(trp_inforec_get_next_hop(rec))); - trp_rentry_set_trust_router(entry, tr_dup_name(trp_inforec_get_trust_router(rec))); - trp_rentry_set_next_hop(entry, tr_dup_name(trp_inforec_get_next_hop(rec))); - if ((trp_rentry_get_apc(entry)==NULL) - ||(trp_rentry_get_realm(entry)==NULL) - ||(trp_rentry_get_peer(entry)==NULL) - ||(trp_rentry_get_trust_router(entry)==NULL) - ||(trp_rentry_get_next_hop(entry)==NULL)) { + trp_route_set_apc(entry, tr_dup_name(trp_inforec_get_comm(rec))); + trp_route_set_realm(entry, tr_dup_name(trp_inforec_get_realm(rec))); + trp_route_set_peer(entry, tr_dup_name(trp_inforec_get_next_hop(rec))); + trp_route_set_trust_router(entry, tr_dup_name(trp_inforec_get_trust_router(rec))); + trp_route_set_next_hop(entry, tr_dup_name(trp_inforec_get_next_hop(rec))); + if ((trp_route_get_apc(entry)==NULL) + ||(trp_route_get_realm(entry)==NULL) + ||(trp_route_get_peer(entry)==NULL) + ||(trp_route_get_trust_router(entry)==NULL) + ||(trp_route_get_next_hop(entry)==NULL)) { /* at least one field could not be allocated */ tr_err("trps_accept_update: unable to allocate all fields for entry."); - trp_rentry_free(entry); + trp_route_free(entry); return TRP_NOMEM; } trp_rtable_add(trps->rtable, entry); @@ -560,13 +560,22 @@ static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_INFOREC *rec) * route (we never accept retractions as new routes), so there is no risk of leaving the expiry * time unset on a new route entry. */ tr_debug("trps_accept_update: accepting route update."); - trp_rentry_set_metric(entry, trp_inforec_get_metric(rec)); - trp_rentry_set_interval(entry, trp_inforec_get_interval(rec)); + trp_route_set_metric(entry, trp_inforec_get_metric(rec)); + trp_route_set_interval(entry, trp_inforec_get_interval(rec)); + + /* check whether the trust router has changed */ + if (0!=tr_name_cmp(trp_route_get_trust_router(entry), + trp_inforec_get_trust_router(rec))) { + /* The name changed. Set this route as triggered. */ + tr_debug("trps_accept_update: trust router for route changed."); + trp_route_set_triggered(entry, 1); + trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec)); /* frees old name */ + } if (!trps_route_retracted(trps, entry)) { tr_debug("trps_accept_update: route not retracted, setting expiry timer."); - trp_rentry_set_expiry(entry, trps_compute_expiry(trps, - trp_rentry_get_interval(entry), - trp_rentry_get_expiry(entry))); + trp_route_set_expiry(entry, trps_compute_expiry(trps, + trp_route_get_interval(entry), + trp_route_get_expiry(entry))); } return TRP_SUCCESS; } @@ -576,15 +585,14 @@ static TRP_RC trps_handle_update(TRPS_INSTANCE *trps, TRP_UPD *upd) { unsigned int feas=0; TRP_INFOREC *rec=NULL; - TRP_RENTRY *route=NULL; + TRP_ROUTE *route=NULL; if (trps_validate_update(trps, upd) != TRP_SUCCESS) { tr_notice("trps_handle_update: received invalid TRP update."); return TRP_ERROR; } - rec=trp_upd_get_inforec(upd); - for (;rec!=NULL; rec=trp_inforec_get_next(rec)) { + for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) { /* validate/sanity check the record update */ if (trps_validate_inforec(trps, rec) != TRP_SUCCESS) { tr_notice("trps_handle_update: invalid record in TRP update."); @@ -596,7 +604,10 @@ static TRP_RC trps_handle_update(TRPS_INSTANCE *trps, TRP_UPD *upd) tr_debug("trps_handle_update: record feasibility=%d", feas); /* do we have an existing route? */ - route=trps_get_route(trps, trp_inforec_get_comm(rec), trp_inforec_get_realm(rec), trp_inforec_get_next_hop(rec)); + route=trps_get_route(trps, + trp_inforec_get_comm(rec), + trp_inforec_get_realm(rec), + trp_inforec_get_next_hop(rec)); if (route!=NULL) { /* there was a route table entry already */ tr_debug("trps_handle_updates: route entry already exists."); @@ -605,7 +616,7 @@ static TRP_RC trps_handle_update(TRPS_INSTANCE *trps, TRP_UPD *upd) trps_accept_update(trps, rec); } else { /* Update is infeasible. Ignore it unless the trust router has changed. */ - if (0!=tr_name_cmp(trp_rentry_get_trust_router(route), + if (0!=tr_name_cmp(trp_route_get_trust_router(route), trp_inforec_get_trust_router(rec))) { /* the trust router associated with the route has changed, treat update as a retraction */ trps_retract_route(trps, route); @@ -622,10 +633,13 @@ static TRP_RC trps_handle_update(TRPS_INSTANCE *trps, TRP_UPD *upd) } /* choose the best route to comm/realm, optionally excluding routes to a particular peer */ -static TRP_RENTRY *trps_find_best_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *exclude_peer) +static TRP_ROUTE *trps_find_best_route(TRPS_INSTANCE *trps, + TR_NAME *comm, + TR_NAME *realm, + TR_NAME *exclude_peer) { - TRP_RENTRY **entry=NULL; - TRP_RENTRY *best=NULL; + TRP_ROUTE **entry=NULL; + TRP_ROUTE *best=NULL; size_t n_entry=0; unsigned int kk=0; unsigned int kk_min=0; @@ -633,15 +647,15 @@ static TRP_RENTRY *trps_find_best_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_N entry=trp_rtable_get_realm_entries(trps->rtable, comm, realm, &n_entry); for (kk=0; kkrtable, &n_apc); size_t n_realm=0, jj=0; TR_NAME **realm=NULL; - TRP_RENTRY *best_route=NULL, *cur_route=NULL; + TRP_ROUTE *best_route=NULL, *cur_route=NULL; unsigned int best_metric=0, cur_metric=0; for (ii=0; iirtable, entry[ii]); /* entry[ii] is no longer valid */ @@ -758,10 +767,10 @@ TRP_RC trps_sweep_routes(TRPS_INSTANCE *trps) } else { /* set metric to infinity and reset timer */ tr_debug("trps_sweep_routes: setting metric to infinity and resetting expiry."); - trp_rentry_set_metric(entry[ii], TRP_METRIC_INFINITY); - trp_rentry_set_expiry(entry[ii], trps_compute_expiry(trps, - trp_rentry_get_interval(entry[ii]), - trp_rentry_get_expiry(entry[ii]))); + trp_route_set_metric(entry[ii], TRP_METRIC_INFINITY); + trp_route_set_expiry(entry[ii], trps_compute_expiry(trps, + trp_route_get_interval(entry[ii]), + trp_route_get_expiry(entry[ii]))); } } } @@ -771,9 +780,9 @@ TRP_RC trps_sweep_routes(TRPS_INSTANCE *trps) } /* select the correct route to comm/realm to be announced to peer */ -static TRP_RENTRY *trps_select_realm_update(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer_gssname) +static TRP_ROUTE *trps_select_realm_update(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer_gssname) { - TRP_RENTRY *route; + TRP_ROUTE *route; /* Take the currently selected route unless it is through the peer we're sending the update to. * I.e., enforce the split horizon rule. */ @@ -784,12 +793,12 @@ static TRP_RENTRY *trps_select_realm_update(TRPS_INSTANCE *trps, TR_NAME *comm, return NULL; } tr_debug("trps_select_realm_update: %s vs %s", peer_gssname->buf, - trp_rentry_get_peer(route)->buf); - if (0==tr_name_cmp(peer_gssname, trp_rentry_get_peer(route))) { + trp_route_get_peer(route)->buf); + if (0==tr_name_cmp(peer_gssname, trp_route_get_peer(route))) { tr_debug("trps_select_realm_update: matched, finding alternate route"); /* the selected entry goes through the peer we're reporting to, choose an alternate */ route=trps_find_best_route(trps, comm, realm, peer_gssname); - if ((route==NULL) || (!trp_metric_is_finite(trp_rentry_get_metric(route)))) + if ((route==NULL) || (!trp_metric_is_finite(trp_route_get_metric(route)))) return NULL; /* don't advertise a nonexistent or retracted route */ } return route; @@ -798,7 +807,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.) If triggered is set, sends only triggered updates. */ -static TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, +static TRP_ROUTE **trps_select_updates_for_peer(TALLOC_CTX *memctx, TRPS_INSTANCE *trps, TR_NAME *peer_gssname, int triggered, @@ -809,15 +818,15 @@ static TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, TR_NAME **realm=NULL; size_t n_realm=0; size_t ii=0, jj=0; - TRP_RENTRY *best=NULL; - TRP_RENTRY **result=NULL; + TRP_ROUTE *best=NULL; + TRP_ROUTE **result=NULL; size_t n_used=0; /* Need to allocate space for the results. For simplicity, we just allocate a block * with space for every route table entry to be returned. This is guaranteed to be large * enough. If the routing table gets very large, this may be wasteful, but that seems * unlikely to be significant in the near future. */ - result=talloc_array(memctx, TRP_RENTRY *, trp_rtable_size(trps->rtable)); + result=talloc_array(memctx, TRP_ROUTE *, trp_rtable_size(trps->rtable)); if (result==NULL) { talloc_free(apc); *n_update=0; @@ -830,7 +839,7 @@ static TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, best=trps_select_realm_update(trps, apc[ii], realm[jj], peer_gssname); /* If we found a route, add it to the list. If triggered!=0, then only * add triggered routes. */ - if ((best!=NULL) && ((!triggered) || trp_rentry_get_triggered(best))) + if ((best!=NULL) && ((!triggered) || trp_route_is_triggered(best))) result[n_used++]=best; } if (realm!=NULL) @@ -845,24 +854,45 @@ static TRP_RENTRY **trps_select_updates_for_peer(TALLOC_CTX *memctx, return result; } +/* add metrics */ +static unsigned int trps_metric_add(unsigned int m1, unsigned int m2) +{ + if (trp_metric_is_invalid(m1) || trp_metric_is_invalid(m2)) + return TRP_METRIC_INVALID; + + if (trp_metric_is_infinite(m1) || trp_metric_is_infinite(m2)) + return TRP_METRIC_INFINITY; + + if (trp_metric_is_finite(m1+m2)) + return m1+m2; + else + return TRP_METRIC_INFINITY; +} + /* 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) +static TRP_INFOREC *trps_route_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trps, TRP_ROUTE *route) { 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))); + if (trp_route_is_local(route)) + linkcost=0; + else { + linkcost=trp_peer_get_linkcost(trps_get_peer(trps, + trp_route_get_next_hop(route))); + } /* 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_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) + if ((trp_inforec_set_comm(rec, trp_route_dup_apc(route)) != TRP_SUCCESS) + ||(trp_inforec_set_realm(rec, trp_route_dup_realm(route)) != TRP_SUCCESS) + ||(trp_inforec_set_trust_router(rec, trp_route_dup_trust_router(route)) != TRP_SUCCESS) + ||(trp_inforec_set_metric(rec, + trps_metric_add(trp_route_get_metric(route), + 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."); + tr_err("trps_route_to_inforec: error creating route update."); talloc_free(rec); rec=NULL; } @@ -877,7 +907,7 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE triggered) TRP_PEER *peer=NULL; TR_MSG msg; /* not a pointer! */ TRP_UPD *upd=NULL; - TRP_RENTRY **update_list=NULL; + TRP_ROUTE **update_list=NULL; TRP_INFOREC *rec=NULL; size_t n_updates=0, ii=0; char *encoded=NULL; @@ -918,7 +948,7 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE triggered) upd=trp_upd_new(tmp_ctx); for (ii=0; iirtable, route); /* should return status */ return TRP_SUCCESS; } +/* steals the peer object */ TRP_RC trps_add_peer(TRPS_INSTANCE *trps, TRP_PEER *peer) { return trp_ptable_add(trps->ptable, peer); -- 2.1.4