#include <dirent.h>
#include <talloc.h>
+#include <tr_cfgwatch.h>
#include <tr_config.h>
#include <tr_debug.h>
-#include <tr.h>
#include <tr_filter.h>
#include <trust_router/tr_constraint.h>
+#include <tr.h>
void tr_print_config (FILE *stream, TR_CFG *cfg) {
fprintf(stream, "tr_print_config: Not yet implemented.");
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"))) {
new->len = strlen(name);
if (new->buf = malloc((new->len)+1)) {
strcpy(new->buf, name);
+ } else {
+ free(new);
+ new=NULL;
}
}
return new;
return s;
}
-
#include <tr_cfgwatch.h>
#include <tr_config.h>
-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);
#include <time.h>
#include <sys/time.h>
+#include <tr_config.h>
+#include <tr_event.h>
+/* 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;
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;
#include <talloc.h>
#include <pthread.h>
+#include <tr.h>
#include <trp_internal.h>
#include <tr_config.h>
+#include <tr_cfgwatch.h>
#include <tr_event.h>
typedef struct tr_trps_events {
+ struct event *trps_ev;
struct tr_socket_event *listen_ev;
struct event *mq_ev;
struct event *connect_ev;
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"
#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 */
#include <talloc.h>
#include <gsscon.h>
-#include <trust_router/tr_dh.h>
#include <tr_mq.h>
#include <tr_msg.h>
#include <trp_ptable.h>
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;
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);
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 */
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);
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);
#include <trp_internal.h>
-typedef struct trp_rentry {
+typedef struct trp_route {
TR_NAME *apc;
TR_NAME *realm;
TR_NAME *peer;
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_ */
#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 */
#include <stdlib.h>
#include <string.h>
#include <talloc.h>
-#include <tr.h>
#include <tr_config.h>
+#include <tr.h>
TR_INSTANCE *tr_create(TALLOC_CTX *mem_ctx) {
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
#include <event2/event.h>
#include <talloc.h>
#include <sys/time.h>
+#include <signal.h>
+#include <pthread.h>
-#include <tr.h>
#include <tid_internal.h>
#include <tr_tid.h>
#include <tr_trp.h>
#include <tr_config.h>
#include <tr_event.h>
#include <tr_cfgwatch.h>
+#include <tr.h>
#include <tr_debug.h>
#define TALLOC_DEBUG_ENABLE 1
}
#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;
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();
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;
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.");
}
/* 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;
}
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);
+#include <stdio.h> /* TODO: remove this --jlr */
#include <pthread.h>
#include <fcntl.h>
#include <event2/event.h>
#include <time.h>
#include <gsscon.h>
+#include <tr.h>
#include <tr_rp.h>
#include <trp_internal.h>
#include <trp_ptable.h>
/* 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;
}
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);
}
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);
{
/* 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)
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);
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 {
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));
}
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) {
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;
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 */
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:
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) {
}
}
+ 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)
}
/* 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;
/* 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;
}
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);
}
/* 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");
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;
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. */
{
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);
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;
/* 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));
* 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);
#include <gsscon.h>
#include <tr_debug.h>
#include <tr_trp.h>
-#include <trust_router/tr_dh.h>
/* command-line option setup */
{
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*/
opts.repeat=1;
argp_parse(&argp, argc, argv, 0, 0, &opts);
- /* TBD -- validity checking, dealing with quotes, etc. */
/* Use standalone logging */
tr_log_open();
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);
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)
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) {
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;
}
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;
}
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;
}
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.");
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);
}
/* 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)
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;
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;
}
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;
}
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)
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;
}
/* 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;
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;
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;
/* 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;
/* 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);
}
/* 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;
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;
/* 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);
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,
trust_router, sep,
next_hop, sep,
entry->selected, sep,
- expiry);
+ entry->local, sep,
+ expiry, sep,
+ entry->triggered);
free(apc);
free(realm);
free(peer);
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; ii<n_entries; ii++)
- trp_rentry_set_triggered(entries[ii], 0);
+ trp_route_set_triggered(entries[ii], 0);
talloc_free(entries);
}
}
size_t n_apcs=0;
TR_NAME **realms=NULL;
size_t n_realms=0;
- TRP_RENTRY **entries=NULL;
+ TRP_ROUTE **entries=NULL;
size_t n_entries=0;
char **tbl_strings=NULL;
size_t ii_tbl=0; /* counts tbl_strings */
entries=trp_rtable_get_realm_entries(rtbl, apcs[ii], realms[jj], &n_entries);
talloc_steal(tmp_ctx, entries);
for (kk=0; kk<n_entries; kk++) {
- tbl_strings[ii_tbl]=trp_rentry_to_str(tmp_ctx, entries[kk], sep);
+ tbl_strings[ii_tbl]=trp_route_to_str(tmp_ctx, entries[kk], sep);
len+=strlen(tbl_strings[ii_tbl]);
ii_tbl++;
}
trpc->server=NULL;
trpc->port=0;
trpc->conn=NULL;
- trpc->dh=NULL;
trpc->mq=tr_mq_new(trpc);
if (trpc->mq==NULL) {
talloc_free(trpc);
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));
#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);
}
/* 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)
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)
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)
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);
* 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;
}
{
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.");
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.");
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);
}
/* 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;
entry=trp_rtable_get_realm_entries(trps->rtable, comm, realm, &n_entry);
for (kk=0; kk<n_entry; kk++) {
- if (trp_rentry_get_metric(entry[kk]) < min_metric) {
- if ((exclude_peer==NULL) || (0!=tr_name_cmp(trp_rentry_get_peer(entry[kk]),
+ if (trp_route_get_metric(entry[kk]) < min_metric) {
+ if ((exclude_peer==NULL) || (0!=tr_name_cmp(trp_route_get_peer(entry[kk]),
exclude_peer))) {
kk_min=kk;
- min_metric=trp_rentry_get_metric(entry[kk]);
- }
+ min_metric=trp_route_get_metric(entry[kk]);
+ }
}
}
- if (trp_metric_is_finite(min_metric));
+ if (trp_metric_is_finite(min_metric))
best=entry[kk_min];
talloc_free(entry);
TR_NAME **apc=trp_rtable_get_apcs(trps->rtable, &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; ii<n_apc; ii++) {
if (best_route==NULL)
best_metric=TRP_METRIC_INFINITY;
else
- best_metric=trp_rentry_get_metric(best_route);
+ best_metric=trp_route_get_metric(best_route);
cur_route=trps_get_selected_route(trps, apc[ii], realm[jj]);
if (cur_route!=NULL) {
- cur_metric=trp_rentry_get_metric(cur_route);
+ cur_metric=trp_route_get_metric(cur_route);
if ((best_metric < cur_metric) && (trp_metric_is_finite(best_metric))) {
/* The new route has a lower metric than the previous, and is finite. Accept. */
- trp_rentry_set_selected(cur_route, 0);
- trp_rentry_set_selected(best_route, 1);
- /* Check whether we just changed trust routers for this destination. If so,
- * we must send a triggered update. (We should probably try to avoid changing
- * trust routers, perhaps accepting a slightly worse metric, but that is todo.) */
- if (0!=tr_name_cmp(trp_rentry_get_trust_router(cur_route),
- trp_rentry_get_trust_router(best_route)))
- trp_rentry_set_triggered(best_route, 1); /* need to send a triggered update for this route */
+ trp_route_set_selected(cur_route, 0);
+ trp_route_set_selected(best_route, 1);
} else if (!trp_metric_is_finite(cur_metric)) /* rejects infinite or invalid metrics */
- trp_rentry_set_selected(cur_route, 0);
- } else if (trp_metric_is_finite(best_metric))
- trp_rentry_set_selected(best_route, 1);
+ trp_route_set_selected(cur_route, 0);
+ } else if (trp_metric_is_finite(best_metric)) {
+ trp_route_set_selected(best_route, 1);
+ }
}
if (realm!=NULL)
talloc_free(realm);
TRP_RC trps_sweep_routes(TRPS_INSTANCE *trps)
{
struct timespec sweep_time={0,0};
- TRP_RENTRY **entry=NULL;
+ TRP_ROUTE **entry=NULL;
size_t n_entry=0;
size_t ii=0;
/* loop over the entries */
for (ii=0; ii<n_entry; ii++) {
- if (trps_expired(trp_rentry_get_expiry(entry[ii]), &sweep_time)) {
+ if (!trp_route_is_local(entry[ii]) && trps_expired(trp_route_get_expiry(entry[ii]), &sweep_time)) {
tr_debug("trps_sweep_routes: route expired.");
- if (!trp_metric_is_finite(trp_rentry_get_metric(entry[ii]))) {
+ if (!trp_metric_is_finite(trp_route_get_metric(entry[ii]))) {
/* flush route */
tr_debug("trps_sweep_routes: metric was infinity, flushing route.");
trp_rtable_remove(trps->rtable, entry[ii]); /* entry[ii] is no longer valid */
} 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])));
}
}
}
}
/* 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. */
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;
/* 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,
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;
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)
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;
}
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;
upd=trp_upd_new(tmp_ctx);
for (ii=0; ii<n_updates; ii++) {
- rec=trps_rentry_to_inforec(tmp_ctx, trps, update_list[ii]);
+ rec=trps_route_to_inforec(tmp_ctx, trps, update_list[ii]);
if (rec==NULL) {
tr_err("trps_update: could not create all update records.");
rc=TRP_ERROR;
return rc;
}
-TRP_RC trps_add_route(TRPS_INSTANCE *trps, TRP_RENTRY *route)
+TRP_RC trps_add_route(TRPS_INSTANCE *trps, TRP_ROUTE *route)
{
trp_rtable_add(trps->rtable, 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);