X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fsubnet.c;h=3d1168dee2600c69416bf91c7ad4ca623195a3ce;hp=3c7ccc536eecfea2e7ab52bbd4d4d35d192e9916;hb=43a6e786648fb666a9b7be8f05c8a173031c9110;hpb=ab7c61b06f6c6e991225f2fcc32d02b8e1084aee diff --git a/src/subnet.c b/src/subnet.c index 3c7ccc53..3d1168de 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -47,15 +47,20 @@ static subnet_t *cache_ipv6_subnet[2]; static bool cache_ipv6_valid[2]; static int cache_ipv6_slot; +static mac_t cache_mac_address[2]; +static subnet_t *cache_mac_subnet[2]; +static bool cache_mac_valid[2]; +static int cache_mac_slot; + void subnet_cache_flush() { cache_ipv4_valid[0] = cache_ipv4_valid[1] = false; cache_ipv6_valid[0] = cache_ipv6_valid[1] = false; + cache_mac_valid[0] = cache_mac_valid[1] = false; } /* Subnet comparison */ -static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) -{ +static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) { int result; result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t)); @@ -71,8 +76,7 @@ static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) return strcmp(a->owner->name, b->owner->name); } -static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) -{ +static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) { int result; result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength; @@ -93,8 +97,7 @@ static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) return strcmp(a->owner->name, b->owner->name); } -static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) -{ +static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) { int result; result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength; @@ -115,8 +118,7 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) return strcmp(a->owner->name, b->owner->name); } -int subnet_compare(const subnet_t *a, const subnet_t *b) -{ +int subnet_compare(const subnet_t *a, const subnet_t *b) { int result; result = a->type - b->type; @@ -132,9 +134,8 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) case SUBNET_IPV6: return subnet_compare_ipv6(a, b); default: - logger(LOG_ERR, _("subnet_compare() was called with unknown subnet type %d, exitting!"), + logger(LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type); - cp_trace(); exit(0); } @@ -143,58 +144,37 @@ int subnet_compare(const subnet_t *a, const subnet_t *b) /* Initialising trees */ -void init_subnets(void) -{ - cp(); - +void init_subnets(void) { subnet_tree = avl_alloc_tree((avl_compare_t) subnet_compare, (avl_action_t) free_subnet); subnet_cache_flush(); } -void exit_subnets(void) -{ - cp(); - +void exit_subnets(void) { avl_delete_tree(subnet_tree); } -avl_tree_t *new_subnet_tree(void) -{ - cp(); - +avl_tree_t *new_subnet_tree(void) { return avl_alloc_tree((avl_compare_t) subnet_compare, NULL); } -void free_subnet_tree(avl_tree_t *subnet_tree) -{ - cp(); - +void free_subnet_tree(avl_tree_t *subnet_tree) { avl_delete_tree(subnet_tree); } /* Allocating and freeing space for subnets */ -subnet_t *new_subnet(void) -{ - cp(); - +subnet_t *new_subnet(void) { return xmalloc_and_zero(sizeof(subnet_t)); } -void free_subnet(subnet_t *subnet) -{ - cp(); - +void free_subnet(subnet_t *subnet) { free(subnet); } /* Adding and removing subnets */ -void subnet_add(node_t *n, subnet_t *subnet) -{ - cp(); - +void subnet_add(node_t *n, subnet_t *subnet) { subnet->owner = n; avl_insert(subnet_tree, subnet); @@ -203,10 +183,7 @@ void subnet_add(node_t *n, subnet_t *subnet) subnet_cache_flush(); } -void subnet_del(node_t *n, subnet_t *subnet) -{ - cp(); - +void subnet_del(node_t *n, subnet_t *subnet) { avl_delete(n->subnet_tree, subnet); avl_delete(subnet_tree, subnet); @@ -215,14 +192,11 @@ void subnet_del(node_t *n, subnet_t *subnet) /* Ascii representation of subnets */ -bool str2net(subnet_t *subnet, const char *subnetstr) -{ +bool str2net(subnet_t *subnet, const char *subnetstr) { int i, l; uint16_t x[8]; int weight = 10; - cp(); - if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d", &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) { if(l < 0 || l > 32) @@ -297,12 +271,9 @@ bool str2net(subnet_t *subnet, const char *subnetstr) return false; } -bool net2str(char *netstr, int len, const subnet_t *subnet) -{ - cp(); - +bool net2str(char *netstr, int len, const subnet_t *subnet) { if(!netstr || !subnet) { - logger(LOG_ERR, _("net2str() was called with netstr=%p, subnet=%p!\n"), netstr, subnet); + logger(LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!\n", netstr, subnet); return false; } @@ -344,9 +315,8 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) default: logger(LOG_ERR, - _("net2str() was called with unknown subnet type %d, exiting!"), + "net2str() was called with unknown subnet type %d, exiting!", subnet->type); - cp_trace(); exit(0); } @@ -355,36 +325,58 @@ bool net2str(char *netstr, int len, const subnet_t *subnet) /* Subnet lookup routines */ -subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) -{ - cp(); - +subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { return avl_search(owner->subnet_tree, subnet); } -subnet_t *lookup_subnet_mac(const mac_t *address) -{ - subnet_t *p, subnet = {0}; +subnet_t *lookup_subnet_mac(const mac_t *address) { + subnet_t *p, *r = NULL, subnet = {0}; + avl_node_t *n; + int i; + + // Check if this address is cached + + for(i = 0; i < 2; i++) { + if(!cache_mac_valid[i]) + continue; + if(!memcmp(address, &cache_mac_address[i], sizeof *address)) + return cache_mac_subnet[i]; + } - cp(); + // Search all subnets for a matching one subnet.type = SUBNET_MAC; subnet.net.mac.address = *address; subnet.owner = NULL; - p = avl_search(subnet_tree, &subnet); + for(n = subnet_tree->head; n; n = n->next) { + p = n->data; + + if(!p || p->type != subnet.type) + continue; + + if(!memcmp(address, &p->net.mac.address, sizeof *address)) { + r = p; + if(p->owner->status.reachable) + break; + } + } + + // Cache the result + + cache_mac_slot = !cache_mac_slot; + memcpy(&cache_mac_address[cache_mac_slot], address, sizeof *address); + cache_mac_subnet[cache_mac_slot] = r; + cache_mac_valid[cache_mac_slot] = true; - return p; + return r; } -subnet_t *lookup_subnet_ipv4(const ipv4_t *address) -{ +subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { subnet_t *p, *r = NULL, subnet = {0}; avl_node_t *n; int i; - cp(); - // Check if this address is cached for(i = 0; i < 2; i++) { @@ -424,14 +416,11 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) return r; } -subnet_t *lookup_subnet_ipv6(const ipv6_t *address) -{ +subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { subnet_t *p, *r = NULL, subnet = {0}; avl_node_t *n; int i; - cp(); - // Check if this address is cached for(i = 0; i < 2; i++) { @@ -538,22 +527,19 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { free(envp[i]); } -void dump_subnets(void) -{ +void dump_subnets(void) { char netstr[MAXNETSTR]; subnet_t *subnet; avl_node_t *node; - cp(); - - logger(LOG_DEBUG, _("Subnet list:")); + logger(LOG_DEBUG, "Subnet list:"); for(node = subnet_tree->head; node; node = node->next) { subnet = node->data; if(!net2str(netstr, sizeof netstr, subnet)) continue; - logger(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name); + logger(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name); } - logger(LOG_DEBUG, _("End of subnet list.")); + logger(LOG_DEBUG, "End of subnet list."); }