.data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
+const struct kr_cc_hash_descr kr_cc_hashes[] = {
+ { kr_cc_compute_fnv64, "FNV-64" },
+ { kr_cc_compute_hmac_sha256_64, "HMAC-SHA256-64" },
+ { NULL, NULL }
+};
+
struct kr_cookie_ctx kr_glob_cookie_ctx = {
.enabled = false,
.current_cs = &dflt_cs
return KNOT_EOK;
}
+cc_compute_func_t *kr_cc_hash_func(const struct kr_cc_hash_descr cc_hashes[],
+ const char *name)
+{
+ if (!cc_hashes || !name) {
+ return NULL;
+ }
+
+ const struct kr_cc_hash_descr *aux_ptr = cc_hashes;
+
+ while (aux_ptr && aux_ptr->hash_func) {
+ assert(aux_ptr->name);
+ if (strcmp(aux_ptr->name, name) == 0) {
+ return aux_ptr->hash_func;
+ }
+ ++aux_ptr;
+ }
+
+ return NULL;
+}
+
+const char *kr_cc_hash_name(const struct kr_cc_hash_descr cc_hashes[],
+ cc_compute_func_t *func)
+{
+ if (!cc_hashes || !func) {
+ return NULL;
+ }
+
+ const struct kr_cc_hash_descr *aux_ptr = cc_hashes;
+ while (aux_ptr && aux_ptr->hash_func) {
+ assert(aux_ptr->name);
+ if (aux_ptr->hash_func == func) {
+ return aux_ptr->name;
+ }
+ ++aux_ptr;
+ }
+
+ return NULL;
+}
+
int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len)
{
if (!sockaddr || !addr || !len) {
typedef int (cc_compute_func_t)(uint8_t *, const void *, const void *,
const struct kr_cookie_secret *);
+/** Holds description of client cookie hashing algorithms. */
+struct kr_cc_hash_descr {
+ cc_compute_func_t *hash_func; /**< Pointer to has function. */
+ const char *name; /**< Hash function name. */
+};
+
+/**
+ * List of available client cookie hash functions.
+ *
+ * Last element contains all null entries.
+ */
+KR_EXPORT
+extern const struct kr_cc_hash_descr kr_cc_hashes[];
+
/** DNS cookies controlling structure. */
struct kr_cookie_ctx {
bool enabled; /**< Enabled/disables DNS cookies functionality. */
uint32_t cache_ttl; /**< TTL used when caching cookies */
- /**< Client cookie computation callback. */
- cc_compute_func_t *cc_compute_func;
+ cc_compute_func_t *cc_compute_func; /**< Client cookie hash computation callback. */
};
/** Global cookie control context. */
KR_EXPORT
extern struct kr_cookie_ctx kr_glob_cookie_ctx;
+/**
+ * @brief Return pointer to client cookie hash function with given name.
+ * @param cc_hashes list of avilable has functions
+ * @param name has function name
+ * @return pointer to function or NULL if not found
+ */
+KR_EXPORT
+cc_compute_func_t *kr_cc_hash_func(const struct kr_cc_hash_descr cc_hashes[],
+ const char *name);
+
+/**
+ * @brief Return name of given client cookie hash function.
+ * @param cc_hashes list of avilable has functions
+ * @param func sought function
+ * @return pointer to string or NULL if not found
+ */
+KR_EXPORT
+const char *kr_cc_hash_name(const struct kr_cc_hash_descr cc_hashes[],
+ cc_compute_func_t *func);
+
/**
* Get pointers to IP address bytes.
* @param sockaddr socket address
#define NAME_ENABLED "enabled"
#define NAME_CLIENT_SECRET "client_secret"
+#define NAME_CLIENT_HASH_FUNC "client_hash_func"
+#define NAME_AVAILABLE_CLIENT_HASH_FUNCS "available_client_hash_funcs"
#define NAME_CACHE_TTL "cache_ttl"
static bool aply_enabled(struct kr_cookie_ctx *cntrl, const JsonNode *node)
return sq;
}
-static bool apply_client_secret(struct kr_cookie_ctx *cntrl, const JsonNode *node)
+static bool apply_client_secret(struct kr_cookie_ctx *cntrl,
+ const JsonNode *node)
{
struct kr_cookie_secret *sq = NULL;
return true;
}
+static bool apply_client_hash_func(struct kr_cookie_ctx *cntrl,
+ const JsonNode *node)
+{
+ if (node->tag == JSON_STRING) {
+ cc_compute_func_t *cc_compute_func = kr_cc_hash_func(kr_cc_hashes,
+ node->string_);
+ if (!cc_compute_func) {
+ return false;
+ }
+ cntrl->cc_compute_func = cc_compute_func;
+ return true;
+ }
+
+ return false;
+}
+
static bool apply_cache_ttl(struct kr_cookie_ctx *cntrl, const JsonNode *node)
{
if (node->tag == JSON_NUMBER) {
return aply_enabled(cntrl, node);
} else if (strcmp(node->key, NAME_CLIENT_SECRET) == 0) {
return apply_client_secret(cntrl, node);
+ } else if (strcmp(node->key, NAME_CLIENT_HASH_FUNC) == 0) {
+ return apply_client_hash_func(cntrl, node);
} else if (strcmp(node->key, NAME_CACHE_TTL) == 0) {
return apply_cache_ttl(cntrl, node);
}
return false;
}
+static bool read_available_cc_hashes(JsonNode *root,
+ struct kr_cookie_ctx *cntrl)
+{
+ assert(root && cntrl);
+
+ JsonNode *array = json_mkarray();
+ if (!array) {
+ return false;
+ }
+
+ const struct kr_cc_hash_descr *aux_ptr = kr_cc_hashes;
+ while (aux_ptr && aux_ptr->hash_func) {
+ assert(aux_ptr->name);
+ JsonNode *element = json_mkstring(aux_ptr->name);
+ if (!element) {
+ goto fail;
+ }
+ json_append_element(array, element);
+ ++aux_ptr;
+ }
+
+ json_append_member(root, NAME_AVAILABLE_CLIENT_HASH_FUNCS, array);
+
+ return true;
+
+fail:
+ if (array) {
+ json_delete(array);
+ }
+ return false;
+}
+
/**
* Get/set DNS cookie related stuff.
*
/* Return current configuration. */
char *result = NULL;
JsonNode *root_node = json_mkobject();
+
json_append_member(root_node, NAME_ENABLED,
json_mkbool(kr_glob_cookie_ctx.enabled));
+
read_secret(root_node, &kr_glob_cookie_ctx);
+
+ const char *name = kr_cc_hash_name(kr_cc_hashes,
+ kr_glob_cookie_ctx.cc_compute_func);
+ assert(name);
+ json_append_member(root_node, NAME_CLIENT_HASH_FUNC,
+ json_mkstring(name));
+
+ read_available_cc_hashes(root_node, &kr_glob_cookie_ctx);
+
json_append_member(root_node, NAME_CACHE_TTL,
json_mknumber(kr_glob_cookie_ctx.cache_ttl));
+
result = json_encode(root_node);
json_delete(root_node);
return result;
kr_glob_cookie_ctx.enabled = false;
kr_glob_cookie_ctx.current_cs = &dflt_cs;
kr_glob_cookie_ctx.cache_ttl = DFLT_COOKIE_TTL;
-
kr_glob_cookie_ctx.cc_compute_func = kr_cc_compute_fnv64;
-// cookies_cache_init(&kr_glob_cookie_ctx.cache, engine);
-
module->data = NULL;
return kr_ok();
}
kr_glob_cookie_ctx.current_cs = &dflt_cs;
-// kr_cache_close(&kr_glob_cookie_ctx.cache);
-
return kr_ok();
}