Skip to content
Snippets Groups Projects
Commit 6379e459 authored by Karel Slaný's avatar Karel Slaný Committed by Ondřej Surý
Browse files

Added support for TTL in cookies cache.

parent 5fbbf97b
Branches
Tags
No related merge requests found
......@@ -116,8 +116,9 @@ static void entry_write(struct kr_cache_entry *dst, struct kr_cache_entry *heade
{
assert(dst && header);
memcpy(dst, header, sizeof(*header));
if (data.data)
if (data.data) {
memcpy(dst->data, data.data, data.len);
}
}
int kr_cookie_cache_insert(struct kr_cache_txn *txn,
......@@ -164,9 +165,9 @@ int kr_cookie_cache_insert(struct kr_cache_txn *txn,
}
int kr_cookie_cache_peek_cookie(struct kr_cache_txn *txn, const void *sockaddr,
const uint8_t **cookie_opt, uint32_t *timestamp)
struct timed_cookie *cookie, uint32_t *timestamp)
{
if (!txn_is_valid(txn) || !sockaddr || !cookie_opt || !timestamp) {
if (!txn_is_valid(txn) || !sockaddr || !cookie || !timestamp) {
return kr_error(EINVAL);
}
......@@ -176,34 +177,36 @@ int kr_cookie_cache_peek_cookie(struct kr_cache_txn *txn, const void *sockaddr,
if (ret != 0) {
return ret;
}
*cookie_opt = entry->data;
cookie->ttl = entry->ttl;
cookie->cookie_opt = entry->data;
return kr_ok();
}
int kr_cookie_cache_insert_cookie(struct kr_cache_txn *txn, const void *sockaddr,
uint8_t *cookie_opt, uint32_t timestamp)
const struct timed_cookie *cookie,
uint32_t timestamp)
{
if (!txn_is_valid(txn) || !sockaddr) {
return kr_error(EINVAL);
}
/* Ignore empty cookie data. */
if (!cookie_opt) {
if (!cookie || !cookie->cookie_opt) {
return kr_ok();
}
/* Prepare header to write. */
struct kr_cache_entry header = {
.timestamp = timestamp,
.ttl = 72000,
.ttl = cookie->ttl,
.rank = KR_RANK_BAD,
.flags = KR_CACHE_FLAG_NONE,
.count = 1
.count = 1 /* Only one entry. */
};
size_t cookie_opt_size = knot_edns_opt_get_length(cookie_opt) + KNOT_EDNS_OPTION_HDRLEN;
size_t cookie_opt_size = knot_edns_opt_get_length(cookie->cookie_opt) + KNOT_EDNS_OPTION_HDRLEN;
knot_db_val_t data = { cookie_opt, cookie_opt_size };
knot_db_val_t data = { (uint8_t *) cookie->cookie_opt, cookie_opt_size };
return kr_cookie_cache_insert(txn, KR_CACHE_COOKIE, sockaddr, &header,
data);
}
......@@ -20,28 +20,69 @@
#define KR_CACHE_COOKIE (KR_CACHE_USER + 'C')
#define COOKIE_TTL 72000
/**
* Peek the cache for asset (tag, socket address).
* @note The 'drift' is the time passed between the inception time and now (in seconds).
* @param txn transaction instance
* @param tag asset tag
* @param sockaddr asset socket address
* @param entry cache entry, will be set to valid pointer or NULL
* @param timestamp current time (will be replaced with drift if successful)
* @return 0 or an error code
*/
KR_EXPORT
int kr_cookie_cache_peek(struct kr_cache_txn *txn, uint8_t tag, const void *sockaddr,
int kr_cookie_cache_peek(struct kr_cache_txn *txn,
uint8_t tag, const void *sockaddr,
struct kr_cache_entry **entry, uint32_t *timestamp);
/**
* Insert asset into cache, replacing any existing data.
* @param txn transaction instance
* @param tag asset tag
* @param sockaddr asset socket address
* @param header filled entry header (ttl and time stamp)
* @param data inserted data
* @return 0 or an error code
*/
KR_EXPORT
int kr_cookie_cache_insert(struct kr_cache_txn *txn,
uint8_t tag, const void *sockaddr,
struct kr_cache_entry *header, knot_db_val_t data);
/**
* Structure used for cookie cache interface.
* @note There is no other way how to pass a ttl into a cookie.
*/
struct timed_cookie {
uint32_t ttl;
const uint8_t *cookie_opt;
};
/**
* Peek the cache for given cookie (socket address)
* @note The 'drift' is the time passed between the cache time of the cookie and now (in seconds).
* @param txn transaction instance
* @param sockaddr socket address
* @param cookie asset
* @param timestamp current time (will be replaced with drift if successful)
* @return 0 or an error code
*/
KR_EXPORT
int kr_cookie_cache_peek_cookie(struct kr_cache_txn *txn, const void *sockaddr,
const uint8_t **cookie_opt, uint32_t *timestamp);
struct timed_cookie *cookie, uint32_t *timestamp);
/**
* Insert a DNS cookie (client and server) entry for the given server signature (IP address).
* @param txn transaction instance
* @param sockaddr server IP address
* @param cookie_opt whole EDNS cookie option (header, client and server)
* @param cookie_size size of the cookie
* @param cookie ttl and whole EDNS cookie option (header, client and server cookies)
* @param timestamp current time
* @return 0 or an errcode
* @return 0 or an error code
*/
KR_EXPORT
int kr_cookie_cache_insert_cookie(struct kr_cache_txn *txn, const void *sockaddr,
uint8_t *cookie_opt, uint32_t timestamp);
const struct timed_cookie *cookie,
uint32_t timestamp);
......@@ -184,20 +184,24 @@ static const uint8_t *peek_and_check_cc(struct kr_cache_txn *txn,
{
assert(txn && sockaddr && cc);
const uint8_t *cached_opt = NULL;
uint32_t timestamp = 0;
struct timed_cookie timed_cookie = { 0, };
int ret = kr_cookie_cache_peek_cookie(txn, sockaddr, &cached_opt,
int ret = kr_cookie_cache_peek_cookie(txn, sockaddr, &timed_cookie,
&timestamp);
if (ret != kr_ok()) {
return NULL;
}
assert(cached_opt);
assert(timed_cookie.cookie_opt);
const uint8_t *cached_cc = knot_edns_opt_get_data((uint8_t *) cached_opt);
/* Ignore the timestamp and time to leave. If the cookie is in cache
* then just use it. The cookie control should be prerformed in the
* cookie module/layer. */
const uint8_t *cached_cc = knot_edns_opt_get_data((uint8_t *) timed_cookie.cookie_opt);
if (0 == memcmp(cc, cached_cc, KNOT_OPT_COOKIE_CLNT)) {
return cached_opt;
return timed_cookie.cookie_opt;
}
return NULL;
......@@ -230,7 +234,8 @@ int kr_request_put_cookie(const struct cookies_control *cntrl,
struct kr_cache_txn txn;
kr_cache_txn_begin(&kr_cookies_control.cache, &txn, KNOT_DB_RDONLY);
const uint8_t *cached_cookie = peek_and_check_cc(&txn, srvr_sockaddr, cc);
const uint8_t *cached_cookie = peek_and_check_cc(&txn, srvr_sockaddr,
cc);
/* This is a very nasty hack that prevents the packet to be corrupted
* when using contemporary 'Cookie interface'. */
......
......@@ -180,34 +180,36 @@ static int server_sockaddr(const struct sockaddr **sockaddr, bool *is_current,
static bool is_cookie_cached(struct kr_cache *cache,
const struct sockaddr *sockaddr,
uint8_t *cookie_opt)
const uint8_t *cookie_opt)
{
assert(cache && sockaddr && cookie_opt);
const uint8_t *cached_cookie = NULL;
struct timed_cookie timed_cookie = { 0, };
uint32_t timestamp = 0;
struct kr_cache_txn txn;
kr_cache_txn_begin(&kr_cookies_control.cache, &txn, KNOT_DB_RDONLY);
int ret = kr_cookie_cache_peek_cookie(&txn, sockaddr, &cached_cookie,
int ret = kr_cookie_cache_peek_cookie(&txn, sockaddr, &timed_cookie,
&timestamp);
if (ret != kr_ok()) {
/* Not cached or error. */
kr_cache_txn_abort(&txn);
return false;
}
assert(cached_cookie);
assert(timed_cookie.cookie_opt);
/* TODO -- Check ttl and drift, if not present then delete cookie. */
uint16_t cookie_opt_size = knot_edns_opt_get_length(cookie_opt) + KNOT_EDNS_OPTION_HDRLEN;
uint16_t cached_cookie_size = knot_edns_opt_get_length((uint8_t *) cached_cookie) + KNOT_EDNS_OPTION_HDRLEN;
uint16_t cached_cookie_size = knot_edns_opt_get_length(timed_cookie.cookie_opt) + KNOT_EDNS_OPTION_HDRLEN;
if (cookie_opt_size != cached_cookie_size) {
kr_cache_txn_abort(&txn);
return false;
}
bool equal = (memcmp(cookie_opt, cached_cookie, cookie_opt_size) == 0);
bool equal = (memcmp(cookie_opt, timed_cookie.cookie_opt, cookie_opt_size) == 0);
kr_cache_txn_abort(&txn);
return equal;
......@@ -279,8 +281,10 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
return ctx->state;
}
struct timed_cookie timed_cookie = { COOKIE_TTL, cookie_opt };
ret = kr_cookie_cache_insert_cookie(&txn, srvr_sockaddr,
cookie_opt,
&timed_cookie,
qry->timestamp.tv_sec);
if (ret != kr_ok()) {
kr_cache_txn_abort(&txn);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment