|
|
|
@ -422,16 +422,22 @@ static GQueue *__interface_list_for_family(sockfamily_t *fam); |
|
|
|
|
|
|
|
static unsigned int __name_family_hash(const struct intf_key *p); |
|
|
|
static int __name_family_eq(const struct intf_key *a, const struct intf_key *b); |
|
|
|
static unsigned int __addr_type_hash(const struct intf_address *p); |
|
|
|
static int __addr_type_eq(const struct intf_address *a, const struct intf_address *b); |
|
|
|
|
|
|
|
TYPED_GHASHTABLE(intf_lookup, struct intf_key, struct logical_intf, __name_family_hash, __name_family_eq, |
|
|
|
g_free, NULL) |
|
|
|
TYPED_GHASHTABLE(intf_rr_lookup, struct intf_key, struct intf_rr, __name_family_hash, __name_family_eq, |
|
|
|
NULL, NULL) |
|
|
|
TYPED_GHASHTABLE(intf_spec_ht, struct intf_address, struct intf_spec, __addr_type_hash, __addr_type_eq, |
|
|
|
NULL, NULL) |
|
|
|
TYPED_GHASHTABLE(local_intf_ht, struct intf_address, local_intf_list, __addr_type_hash, __addr_type_eq, |
|
|
|
NULL, NULL) |
|
|
|
|
|
|
|
static intf_lookup __logical_intf_name_family_hash; // name + family -> struct logical_intf |
|
|
|
static intf_rr_lookup __logical_intf_name_family_rr_hash; // name + family -> struct intf_rr |
|
|
|
static GHashTable *__intf_spec_addr_type_hash; // addr + type -> struct intf_spec |
|
|
|
static GHashTable *__local_intf_addr_type_hash; // addr + type -> GList of struct local_intf |
|
|
|
static intf_spec_ht __intf_spec_addr_type_hash; |
|
|
|
static local_intf_ht __local_intf_addr_type_hash; |
|
|
|
static GQueue __preferred_lists_for_family[__SF_LAST]; |
|
|
|
|
|
|
|
GQueue all_local_interfaces = G_QUEUE_INIT; |
|
|
|
@ -644,28 +650,23 @@ static int __name_family_eq(const struct intf_key *A, const struct intf_key *B) |
|
|
|
return str_equal(&A->name, &B->name) && A->preferred_family == B->preferred_family; |
|
|
|
} |
|
|
|
|
|
|
|
static unsigned int __addr_type_hash(const void *p) { |
|
|
|
const struct intf_address *addr = p; |
|
|
|
static unsigned int __addr_type_hash(const struct intf_address *addr) { |
|
|
|
return sockaddr_hash(&addr->addr) ^ g_direct_hash(addr->type); |
|
|
|
} |
|
|
|
static int __addr_type_eq(const void *a, const void *b) { |
|
|
|
const struct intf_address *A = a, *B = b; |
|
|
|
static int __addr_type_eq(const struct intf_address *A, const struct intf_address *B) { |
|
|
|
return sockaddr_eq(&A->addr, &B->addr) && A->type == B->type; |
|
|
|
} |
|
|
|
|
|
|
|
static void __insert_local_intf_addr_type(const struct intf_address *addr, const struct local_intf *intf) { |
|
|
|
GList *l; |
|
|
|
|
|
|
|
l = g_hash_table_lookup(__local_intf_addr_type_hash, addr); |
|
|
|
l = g_list_prepend(l, (void *) intf); |
|
|
|
g_hash_table_replace(__local_intf_addr_type_hash, (void *) addr, l); |
|
|
|
static void __insert_local_intf_addr_type(struct intf_address *addr, struct local_intf *intf) { |
|
|
|
__auto_type l = t_hash_table_lookup(__local_intf_addr_type_hash, addr); |
|
|
|
l = t_list_prepend(l, intf); |
|
|
|
t_hash_table_replace(__local_intf_addr_type_hash, addr, l); |
|
|
|
} |
|
|
|
int is_local_endpoint(const struct intf_address *addr, unsigned int port) { |
|
|
|
GList *l; |
|
|
|
const struct local_intf *intf; |
|
|
|
const struct intf_spec *spec; |
|
|
|
|
|
|
|
l = g_hash_table_lookup(__local_intf_addr_type_hash, addr); |
|
|
|
__auto_type l = t_hash_table_lookup(__local_intf_addr_type_hash, addr); |
|
|
|
if (!l) |
|
|
|
return 0; |
|
|
|
while (l) { |
|
|
|
@ -821,7 +822,7 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam, bool |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
spec = g_hash_table_lookup(__intf_spec_addr_type_hash, &ifa->local_address); |
|
|
|
spec = t_hash_table_lookup(__intf_spec_addr_type_hash, &ifa->local_address); |
|
|
|
|
|
|
|
if (!spec) { |
|
|
|
spec = g_slice_alloc0(sizeof(*spec)); |
|
|
|
@ -834,7 +835,7 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam, bool |
|
|
|
/* pre-fill the range of used ports */ |
|
|
|
__append_free_ports_to_int(spec); |
|
|
|
|
|
|
|
g_hash_table_insert(__intf_spec_addr_type_hash, &spec->local_address, spec); |
|
|
|
t_hash_table_insert(__intf_spec_addr_type_hash, &spec->local_address, spec); |
|
|
|
} |
|
|
|
else { |
|
|
|
if (spec->port_pool.min != ifa->port_min |
|
|
|
@ -870,8 +871,8 @@ void interfaces_init(intf_config_q *interfaces) { |
|
|
|
/* init everything */ |
|
|
|
__logical_intf_name_family_hash = intf_lookup_new(); |
|
|
|
__logical_intf_name_family_rr_hash = intf_rr_lookup_new(); |
|
|
|
__intf_spec_addr_type_hash = g_hash_table_new(__addr_type_hash, __addr_type_eq); |
|
|
|
__local_intf_addr_type_hash = g_hash_table_new(__addr_type_hash, __addr_type_eq); |
|
|
|
__intf_spec_addr_type_hash = intf_spec_ht_new(); |
|
|
|
__local_intf_addr_type_hash = local_intf_ht_new(); |
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS(__preferred_lists_for_family); i++) |
|
|
|
g_queue_init(&__preferred_lists_for_family[i]); |
|
|
|
@ -897,18 +898,16 @@ void interfaces_init(intf_config_q *interfaces) { |
|
|
|
} |
|
|
|
|
|
|
|
void interfaces_exclude_port(unsigned int port) { |
|
|
|
GList *vals, *l, *ll; |
|
|
|
GList *ll; |
|
|
|
struct intf_spec *spec; |
|
|
|
|
|
|
|
struct port_pool *pp; |
|
|
|
GQueue * free_ports_q; |
|
|
|
GHashTable * free_ports_ht; |
|
|
|
|
|
|
|
vals = g_hash_table_get_values(__intf_spec_addr_type_hash); |
|
|
|
|
|
|
|
for (l = vals; l; l = l->next) { |
|
|
|
spec = l->data; |
|
|
|
|
|
|
|
intf_spec_ht_iter iter; |
|
|
|
t_hash_table_iter_init(&iter, __intf_spec_addr_type_hash); |
|
|
|
while (t_hash_table_iter_next(&iter, NULL, &spec)) { |
|
|
|
pp = &spec->port_pool; |
|
|
|
free_ports_q = &pp->free_ports_q; |
|
|
|
free_ports_ht = pp->free_ports_ht; |
|
|
|
@ -919,8 +918,6 @@ void interfaces_exclude_port(unsigned int port) { |
|
|
|
reserve_port(free_ports_q, free_ports_ht, ll, port); |
|
|
|
mutex_unlock(&pp->free_list_lock); |
|
|
|
} |
|
|
|
|
|
|
|
g_list_free(vals); |
|
|
|
} |
|
|
|
|
|
|
|
struct local_intf *get_interface_address(const struct logical_intf *lif, sockfamily_t *fam) { |
|
|
|
@ -3226,7 +3223,6 @@ void play_buffered(struct jb_packet *cp) { |
|
|
|
|
|
|
|
void interfaces_free(void) { |
|
|
|
struct local_intf *ifc; |
|
|
|
GList *ll; |
|
|
|
|
|
|
|
while ((ifc = g_queue_pop_head(&all_local_interfaces))) { |
|
|
|
free(ifc->ice_foundation.s); |
|
|
|
@ -3236,17 +3232,17 @@ void interfaces_free(void) { |
|
|
|
|
|
|
|
t_hash_table_destroy(__logical_intf_name_family_hash); |
|
|
|
|
|
|
|
ll = g_hash_table_get_values(__local_intf_addr_type_hash); |
|
|
|
for (GList *l = ll; l; l = l->next) { |
|
|
|
GList *k = l->data; |
|
|
|
g_list_free(k); |
|
|
|
} |
|
|
|
g_list_free(ll); |
|
|
|
g_hash_table_destroy(__local_intf_addr_type_hash); |
|
|
|
local_intf_ht_iter l_iter; |
|
|
|
t_hash_table_iter_init(&l_iter, __local_intf_addr_type_hash); |
|
|
|
local_intf_list *lifl; |
|
|
|
while (t_hash_table_iter_next(&l_iter, NULL, &lifl)) |
|
|
|
t_list_free(lifl); |
|
|
|
t_hash_table_destroy(__local_intf_addr_type_hash); |
|
|
|
|
|
|
|
ll = g_hash_table_get_values(__intf_spec_addr_type_hash); |
|
|
|
for (GList *l = ll; l; l = l->next) { |
|
|
|
struct intf_spec *spec = l->data; |
|
|
|
intf_spec_ht_iter s_iter; |
|
|
|
t_hash_table_iter_init(&s_iter, __intf_spec_addr_type_hash); |
|
|
|
struct intf_spec *spec; |
|
|
|
while (t_hash_table_iter_next(&s_iter, NULL, &spec)) { |
|
|
|
struct port_pool *pp = &spec->port_pool; |
|
|
|
if (pp->free_ports_ht) { |
|
|
|
g_hash_table_destroy(pp->free_ports_ht); |
|
|
|
@ -3255,8 +3251,7 @@ void interfaces_free(void) { |
|
|
|
mutex_destroy(&pp->free_list_lock); |
|
|
|
g_slice_free1(sizeof(*spec), spec); |
|
|
|
} |
|
|
|
g_list_free(ll); |
|
|
|
g_hash_table_destroy(__intf_spec_addr_type_hash); |
|
|
|
t_hash_table_destroy(__intf_spec_addr_type_hash); |
|
|
|
|
|
|
|
intf_rr_lookup_iter r_iter; |
|
|
|
t_hash_table_iter_init(&r_iter, __logical_intf_name_family_rr_hash); |
|
|
|
|