4 #include <trust_router/tr_name.h>
5 #include <trp_internal.h>
6 #include <trp_rtable.h>
9 /* Note: be careful mixing talloc with glib. */
11 static int trp_rentry_destructor(void *obj)
13 TRP_RENTRY *entry=talloc_get_type_abort(obj, TRP_RENTRY);
15 tr_free_name(entry->apc);
16 if (entry->realm!=NULL)
17 tr_free_name(entry->realm);
18 if (entry->trust_router!=NULL)
19 tr_free_name(entry->trust_router);
20 if (entry->peer!=NULL)
21 tr_free_name(entry->peer);
22 if (entry->next_hop!=NULL)
23 tr_free_name(entry->next_hop);
27 TRP_RENTRY *trp_rentry_new(TALLOC_CTX *mem_ctx)
29 TRP_RENTRY *entry=talloc(mem_ctx, TRP_RENTRY);
33 entry->trust_router=NULL;
37 entry->expiry=talloc(entry, struct timespec);
38 if (entry->expiry==NULL) {
42 talloc_set_destructor((void *)entry, trp_rentry_destructor);
44 tr_debug("trp_rentry_new: %p", entry);
48 void trp_rentry_free(TRP_RENTRY *entry)
54 void trp_rentry_set_apc(TRP_RENTRY *entry, TR_NAME *apc)
59 TR_NAME *trp_rentry_get_apc(TRP_RENTRY *entry)
64 void trp_rentry_set_realm(TRP_RENTRY *entry, TR_NAME *realm)
69 TR_NAME *trp_rentry_get_realm(TRP_RENTRY *entry)
74 void trp_rentry_set_trust_router(TRP_RENTRY *entry, TR_NAME *tr)
76 entry->trust_router=tr;
79 TR_NAME *trp_rentry_get_trust_router(TRP_RENTRY *entry)
81 return entry->trust_router;
84 void trp_rentry_set_peer(TRP_RENTRY *entry, TR_NAME *peer)
89 TR_NAME *trp_rentry_get_peer(TRP_RENTRY *entry)
94 void trp_rentry_set_metric(TRP_RENTRY *entry, unsigned int metric)
99 unsigned int trp_rentry_get_metric(TRP_RENTRY *entry)
101 return entry->metric;
104 void trp_rentry_set_next_hop(TRP_RENTRY *entry, TR_NAME *next_hop)
106 entry->next_hop=next_hop;
109 TR_NAME *trp_rentry_get_next_hop(TRP_RENTRY *entry)
111 return entry->next_hop;
114 void trp_rentry_set_selected(TRP_RENTRY *entry, int sel)
119 int trp_rentry_get_selected(TRP_RENTRY *entry)
121 return entry->selected;
124 /* copies incoming value, does not assume responsibility for freeing */
125 void trp_rentry_set_expiry(TRP_RENTRY *entry, struct timespec *exp)
127 entry->expiry->tv_sec=exp->tv_sec;
128 entry->expiry->tv_nsec=exp->tv_nsec;
131 struct timespec *trp_rentry_get_expiry(TRP_RENTRY *entry)
133 return entry->expiry;
137 /* result must be freed with g_free */
138 static gchar *tr_name_to_g_str(const TR_NAME *n)
140 gchar *s=g_strndup(n->buf, n->len);
144 /* hash function for TR_NAME keys */
145 static guint trp_tr_name_hash(gconstpointer key)
147 const TR_NAME *name=(TR_NAME *)key;
148 gchar *s=tr_name_to_g_str(name);
149 guint hash=g_str_hash(s);
154 /* hash equality function for TR_NAME keys */
155 static gboolean trp_tr_name_equal(gconstpointer key1, gconstpointer key2)
157 const TR_NAME *n1=(TR_NAME *)key1;
158 const TR_NAME *n2=(TR_NAME *)key2;
159 gchar *s1=tr_name_to_g_str(n1);
160 gchar *s2=tr_name_to_g_str(n2);
161 gboolean equal=g_str_equal(s1, s2);
167 /* free a value to the top level rtable (a hash of all entries in the apc) */
168 static void trp_rtable_destroy_table(gpointer data)
170 g_hash_table_destroy(data);
173 static void trp_rtable_destroy_rentry(gpointer data)
175 trp_rentry_free(data);
178 TRP_RTABLE *trp_rtable_new(void)
180 GHashTable *new=g_hash_table_new_full(trp_tr_name_hash,
182 NULL, /* no need to free the key, it is part of the TRP_RENTRY */
183 trp_rtable_destroy_table);
184 tr_debug("trp_rtable_new: %p", new);
188 void trp_rtable_free(TRP_RTABLE *rtbl)
190 g_hash_table_destroy(rtbl);
193 static GHashTable *trp_rtbl_get_or_add_table(GHashTable *tbl, TR_NAME *key, GDestroyNotify destroy)
195 GHashTable *val_tbl=NULL;
197 val_tbl=g_hash_table_lookup(tbl, key);
199 val_tbl=g_hash_table_new_full(trp_tr_name_hash,
201 NULL, /* no need to free the key */
203 tr_debug("tr_rtbl_get_or_add_table: %p", val_tbl, trp_rtable_destroy_table);
204 g_hash_table_insert(tbl, key, val_tbl);
209 void trp_rtable_add(TRP_RTABLE *rtbl, TRP_RENTRY *entry)
211 GHashTable *apc_tbl=NULL;
212 GHashTable *realm_tbl=NULL;
214 apc_tbl=trp_rtbl_get_or_add_table(rtbl, entry->apc, trp_rtable_destroy_table);
215 realm_tbl=trp_rtbl_get_or_add_table(apc_tbl, entry->realm, trp_rtable_destroy_rentry);
216 g_hash_table_insert(realm_tbl, entry->peer, entry); /* destroys and replaces a duplicate */
219 void trp_rtable_remove(TRP_RTABLE *rtbl, TRP_RENTRY *entry)
221 GHashTable *apc_tbl=NULL;
222 GHashTable *realm_tbl=NULL;
224 apc_tbl=g_hash_table_lookup(rtbl, entry->apc);
227 realm_tbl=g_hash_table_lookup(apc_tbl, entry->realm);
230 g_hash_table_remove(realm_tbl, entry->peer);
233 /* Get all entries in an apc. Returned as a talloc'ed array in the NULL
234 * context. Caller should free these. */
235 size_t trp_rtable_get_apc(TRP_RTABLE *rtbl, TR_NAME *apc, TRP_RENTRY **ret)
237 GHashTable *apc_tbl=NULL;
238 size_t len=0; /* length of return array */
241 GList *realm_entries=NULL;
242 GList *p1=NULL, *p2=NULL;
244 apc_tbl=g_hash_table_lookup(rtbl, apc);
248 realms=g_hash_table_get_values(apc_tbl);
249 /* make two passes: first count the entries, then allocate and populate the output array */
250 for (p1=realms; p1!=NULL; p1=g_list_next(p1))
251 len+=g_hash_table_size(p1->data);
257 *ret=talloc_array(NULL, TRP_RENTRY, len);
259 tr_crit("trp_rtable_get_apc: could not allocate return array.");
265 for (p1=realms; p1!=NULL; p1=g_list_next(p1)) {
266 realm_entries=g_hash_table_get_values(p1->data);
267 for (p2=realm_entries; p2!=NULL; p2=g_list_next(p2)) {
268 memcpy(*ret+ii, p2->data, sizeof(TRP_RENTRY));
271 g_list_free(realm_entries);
278 /* Get all entries in an apc/realm. Returns as a talloc'ed array in
279 * the NULL context via . Caller must free these. */
280 size_t trp_rtable_get_realm(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, TRP_RENTRY **ret)
282 GHashTable *apc_tbl=NULL;
283 GHashTable *realm_tbl=NULL;
289 apc_tbl=g_hash_table_lookup(rtbl, apc);
292 realm_tbl=g_hash_table_lookup(apc_tbl, realm);
295 entries=g_hash_table_get_values(realm_tbl);
296 len=g_hash_table_size(realm_tbl);
297 *ret=talloc_array(NULL, TRP_RENTRY, len);
299 tr_crit("trp_rtable_get_realm: could not allocate return array.");
302 for (ii=0,p=entries; p!=NULL; ii++,p=g_list_next(p))
303 memcpy(*ret+ii, p->data, sizeof(TRP_RENTRY));
304 g_list_free(entries);
308 /* Gets a single entry, in the NULL talloc context. Caller must free. */
309 TRP_RENTRY *trp_rtable_get_entry(TRP_RTABLE *rtbl, TR_NAME *apc, TR_NAME *realm, TR_NAME *peer)
311 GHashTable *apc_tbl=NULL;
312 GHashTable *realm_tbl=NULL;
314 apc_tbl=g_hash_table_lookup(rtbl, apc);
317 realm_tbl=g_hash_table_lookup(apc_tbl, realm);
320 return (TRP_RENTRY *)g_hash_table_lookup(realm_tbl, peer);