isc_result_t isc_ht_delete(isc_ht_t *ht, const unsigned char *key, isc_uint32_t keysize) { isc_ht_node_t *node, *prev; isc_uint32_t hash; REQUIRE(ISC_HT_VALID(ht)); REQUIRE(key != NULL && keysize > 0); prev = NULL; hash = isc_hash_function(key, keysize, ISC_TRUE, NULL); node = ht->table[hash & ht->mask]; while (node != NULL) { if (keysize == node->keysize && memcmp(key, node->key, keysize) == 0) { if (prev == NULL) ht->table[hash & ht->mask] = node->next; else prev->next = node->next; isc_mem_put(ht->mctx, node, sizeof(isc_ht_node_t) + node->keysize); ht->count--; return (ISC_R_SUCCESS); } prev = node; node = node->next; } return (ISC_R_NOTFOUND); }
isc_result_t isc_ht_add(isc_ht_t *ht, const unsigned char *key, isc_uint32_t keysize, void *value) { isc_ht_node_t *node; isc_uint32_t hash; REQUIRE(ISC_HT_VALID(ht)); REQUIRE(key != NULL && keysize > 0); hash = isc_hash_function(key, keysize, ISC_TRUE, NULL); node = ht->table[hash & ht->mask]; while (node != NULL) { if (keysize == node->keysize && memcmp(key, node->key, keysize) == 0) { return (ISC_R_EXISTS); } node = node->next; } node = isc_mem_get(ht->mctx, sizeof(isc_ht_node_t) + keysize); if (node == NULL) return (ISC_R_NOMEMORY); memmove(node->key, key, keysize); node->keysize = keysize; node->next = ht->table[hash & ht->mask]; node->value = value; ht->count++; ht->table[hash & ht->mask] = node; return (ISC_R_SUCCESS); }
isc_result_t isc_ht_find(const isc_ht_t *ht, const unsigned char *key, isc_uint32_t keysize, void **valuep) { isc_ht_node_t *node; isc_uint32_t hash; REQUIRE(ISC_HT_VALID(ht)); REQUIRE(key != NULL && keysize > 0); hash = isc_hash_function(key, keysize, ISC_TRUE, NULL); node = ht->table[hash & ht->mask]; while (node != NULL) { if (keysize == node->keysize && memcmp(key, node->key, keysize) == 0) { if (valuep != NULL) *valuep = node->value; return (ISC_R_SUCCESS); } node = node->next; } return (ISC_R_NOTFOUND); }
unsigned int isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) { unsigned int length = 0; const unsigned char *s = NULL; unsigned int h = 0; unsigned int p = 0; const struct in6_addr *in6; REQUIRE(sockaddr != NULL); switch (sockaddr->type.sa.sa_family) { case AF_INET: s = (const unsigned char *)&sockaddr->type.sin.sin_addr; p = ntohs(sockaddr->type.sin.sin_port); length = sizeof(sockaddr->type.sin.sin_addr.s_addr); break; case AF_INET6: in6 = &sockaddr->type.sin6.sin6_addr; s = (const unsigned char *)in6; if (IN6_IS_ADDR_V4MAPPED(in6)) { s += 12; length = sizeof(sockaddr->type.sin.sin_addr.s_addr); } else length = sizeof(sockaddr->type.sin6.sin6_addr); p = ntohs(sockaddr->type.sin6.sin6_port); break; default: UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR, ISC_MSG_UNKNOWNFAMILY, "unknown address family: %d"), (int)sockaddr->type.sa.sa_family); s = (const unsigned char *)&sockaddr->type; length = sockaddr->length; p = 0; } h = isc_hash_function(s, length, ISC_TRUE, NULL); if (!address_only) h = isc_hash_function(&p, sizeof(p), ISC_TRUE, &h); return (h); }
isc_result_t isc_ht_iter_delcurrent_next(isc_ht_iter_t *it) { isc_result_t result = ISC_R_SUCCESS; isc_ht_node_t *to_delete = NULL; isc_ht_node_t *prev = NULL; isc_ht_node_t *node = NULL; isc_uint32_t hash; isc_ht_t *ht; REQUIRE(it != NULL); REQUIRE(it->cur != NULL); to_delete = it->cur; ht = it->ht; it->cur = it->cur->next; if (it->cur == NULL) { do { it->i++; } while (it->i < ht->size && ht->table[it->i] == NULL); if (it->i >= ht->size) result = ISC_R_NOMORE; else it->cur = ht->table[it->i]; } hash = isc_hash_function(to_delete->key, to_delete->keysize, ISC_TRUE, NULL); node = ht->table[hash & ht->mask]; while (node != to_delete) { prev = node; node = node->next; INSIST(node != NULL); } if (prev == NULL) ht->table[hash & ht->mask] = node->next; else prev->next = node->next; isc_mem_put(ht->mctx, node, sizeof(isc_ht_node_t) + node->keysize); ht->count--; return (result); }