Commit e2f0680a authored by Geoff Simmons's avatar Geoff Simmons

Start addings stats, beginning with the ops counters for default VFPs.

parent a2871806
......@@ -57,6 +57,7 @@ PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto])
VARNISH_PREREQ([trunk])
VARNISH_VMODS([ece])
VARNISH_COUNTERS([ece])
VMOD_TESTS="$(cd $srcdir/src && echo tests/*.vtc)"
AC_SUBST(VMOD_TESTS)
......
......@@ -22,7 +22,11 @@ libvmod_ece_la_SOURCES = \
nodist_libvmod_ece_la_SOURCES = \
vcc_if.c \
vcc_if.h
vcc_if.h \
VSC_ece.h \
VSC_ece.c
@BUILD_VSC_ECE@
vmod_ece.lo: $(nodist_libvmod_ece_la_SOURCES)
......@@ -102,6 +106,7 @@ endif
EXTRA_DIST = \
vmod_ece.vcc \
ece.vsc \
$(VMOD_TESTS)
CLEANFILES = \
......@@ -111,7 +116,9 @@ CLEANFILES = \
$(builddir)/vmod_ece.man.rst \
$(builddir)/vmod_ece.3 \
$(builddir)/*.gcda \
$(builddir)/*.gcno
$(builddir)/*.gcno \
$(builddir)/VSC_brotli.c \
$(builddir)/VSC_brotli.h
clean-local:
@rm -rf $(builddir)/coverage
..
This is *NOT* a RST file but the syntax has been chosen so
that it may become an RST file at some later date.
.. varnish_vsc_begin:: ece
:oneliner: VMOD ece stats (encrypted content-encoding)
:order: 90
.. varnish_vsc:: ops
:type: counter
:oneliner: Operations
Total number of en-/decryption operations
.. varnish_vsc_end:: ece
......@@ -11,6 +11,10 @@ varnish v1 -vsc LCK.ece.key_mem.*
varnish v1 -expect LCK.ece.key_mem.creat == 1
varnish v1 -expect LCK.ece.key_mem.locks == 1
varnish v1 -vsc ECE.*
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 0
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 0
varnish v1 -vcl {backend b { .host = "${bad_ip}"; }}
varnish v1 -cli "vcl.list"
......@@ -27,6 +31,9 @@ varnish v1 -cli "vcl.list"
# Lock destroyed on last discard (log shows no LCK.ece.key_mem.*).
varnish v1 -vsc LCK.*
# Stats destroyed on last discard (logs shows nothing for ECE.*)
varnish v1 -vsc ECE.*
varnish v1 -vcl {
import ${vmod_ece};
backend b { .host = "${bad_ip}"; }
......@@ -60,3 +67,8 @@ client c1 {
varnish v1 -vsc LCK.ece.key_mem.*
varnish v1 -expect LCK.ece.key_mem.creat == 1
varnish v1 -expect LCK.ece.key_mem.locks == 1
# Stats exist again after new load.
varnish v1 -vsc ECE.*
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 0
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 0
......@@ -70,6 +70,8 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VfpAcct" {
expect * = End
} -run
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 2
## Corner cases
server s1 -wait
......@@ -127,6 +129,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 3
## Errors
server s1 -wait
......@@ -169,6 +173,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 4
server s1 -wait
server s1 {
# No body but 53 bytes expected, VFP below ece-decrypt fails.
......@@ -184,6 +190,8 @@ client c1 {
expect resp.reason == "Backend fetch failed"
} -run
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 5
server s1 -wait
server s1 {
# Header prefix is complete but id is incomplete
......@@ -209,6 +217,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 6
server s1 -wait
server s1 {
# 23 bytes for the header expected, but 22 sent, low-level VFP fails
......@@ -226,6 +236,8 @@ client c1 {
expect resp.reason == "Backend fetch failed"
} -run
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 7
server s1 -wait
server s1 {
# Record length 17 too small
......@@ -251,6 +263,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 8
server s1 -wait
server s1 {
# Record length exceeds default max
......@@ -276,6 +290,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 9
server s1 -wait
server s1 {
# Record shorter than allowable minimum.
......@@ -301,6 +317,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 10
server s1 -wait
server s1 {
# Header valid, but decryption fails
......@@ -327,3 +345,5 @@ client c1 {
} -run
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 11
......@@ -60,6 +60,8 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VfpAcct" {
expect * = End
} -run
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 1
# set-salt error
varnish v1 -vcl+backend {
import ${vmod_ece};
......@@ -85,3 +87,5 @@ client c1 {
} -run
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 2
......@@ -69,6 +69,10 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VfpAcct" {
expect * = End
} -run
# ops not incremented when bypassed due to the empty body, or when the
# VFP declines due to Content-Encoding
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 1
server s1 -wait
server s1 {
rxreq
......@@ -90,6 +94,8 @@ client c1 {
logexpect l1 -wait
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 2
server s1 -wait
server s1 {
# No body but 4711 bytes expected, VFP below ece-decrypt fails.
......@@ -104,3 +110,5 @@ client c1 {
expect resp.status == 503
expect resp.reason == "Backend fetch failed"
} -run
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 2
......@@ -148,3 +148,6 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VfpAcct" {
expect * = VfpAcct {^ece_encrypt \d+ \d+$}
expect * = End
} -run
varnish v1 -expect ECE.vfp.ece_encrypt.ops == 6
varnish v1 -expect ECE.vfp.ece_decrypt.ops == 6
......@@ -28,6 +28,8 @@
#include "cache/cache_filter.h"
#include "VSC_ece.h"
#define MIN_RS 18
struct vfp_settings {
......@@ -37,6 +39,14 @@ struct vfp_settings {
uint32_t rs;
};
struct vfp_cfg {
unsigned magic;
#define VFP_CFG_MAGIC 0x75413842
struct vfp_settings *settings;
struct VSC_ece *stats;
struct vsc_seg *vsc_seg;
};
/* VFP .fini method for both encrypt and decrypt */
void v_matchproto_(vfp_fini_f) vfp_common_fini(struct vfp_ctx *ctx,
struct vfp_entry *ent);
......
......@@ -48,9 +48,10 @@
#define HDR_LEN(hdr) ((hdr)->next_in - (hdr)->hdr)
static enum vfp_status
decrypt_init(struct vfp_ctx *ctx, struct ece *ece,
const struct vfp_settings *settings, const char *vfp_name)
decrypt_init(struct vfp_ctx *ctx, struct ece *ece, const struct vfp_cfg *cfg,
const char *vfp_name)
{
struct vfp_settings *settings;
struct ece_hdrbuf *hdr;
enum vfp_status vp;
size_t len;
......@@ -63,7 +64,8 @@ decrypt_init(struct vfp_ctx *ctx, struct ece *ece,
CHECK_OBJ_NOTNULL(ece, ECE_MAGIC);
CHECK_OBJ_NOTNULL(ece->crypto, ECE_CRYPTO_MAGIC);
CHECK_OBJ_NOTNULL(ece->hdr, ECE_HDRBUF_MAGIC);
CHECK_OBJ_NOTNULL(settings, VFP_SETTINGS_MAGIC);
CHECK_OBJ_NOTNULL(cfg, VFP_CFG_MAGIC);
CHECK_OBJ_NOTNULL(cfg->settings, VFP_SETTINGS_MAGIC);
AN(vfp_name);
AZ(ece->rs);
AZ(ece->chunksz);
......@@ -72,6 +74,7 @@ decrypt_init(struct vfp_ctx *ctx, struct ece *ece,
AN(hdr->hdr);
AN(hdr->next_in);
AN(hdr->avail_in);
settings = cfg->settings;
if (HDR_LEN(hdr) < HDR_PFX_LEN) {
len = HDR_PFX_LEN - HDR_LEN(hdr);
......@@ -239,9 +242,12 @@ enum vfp_status v_matchproto_(vfp_init_f)
vfp_decrypt_init(struct vfp_ctx *ctx, struct vfp_entry *ent)
{
struct ece *ece;
const struct vfp_cfg *cfg;
CHECK_OBJ_NOTNULL(ctx, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ent, VFP_ENTRY_MAGIC);
AN(ent->vfp);
CAST_OBJ_NOTNULL(cfg, ent->vfp->priv1, VFP_CFG_MAGIC);
/* XXX implement me */
if (http_GetStatus(ctx->resp) == 206)
......@@ -250,6 +256,9 @@ vfp_decrypt_init(struct vfp_ctx *ctx, struct vfp_entry *ent)
if (!http_HdrIs(ctx->resp, H_Content_Encoding, "aes128gcm"))
return (VFP_NULL);
if (cfg->stats != NULL)
cfg->stats->ops++;
if (common_alloc(ctx, &ece, 0) == VFP_ERROR)
return (VFP_ERROR);
ent->priv1 = ece;
......@@ -273,7 +282,7 @@ vfp_decrypt_pull(struct vfp_ctx *ctx, struct vfp_entry *ent, void *ptr,
{
struct ece *ece;
struct ece_stream *stream;
const struct vfp_settings *settings;
const struct vfp_cfg *cfg;
unsigned char *p = ptr;
enum vfp_status vp = VFP_OK;
......@@ -290,8 +299,8 @@ vfp_decrypt_pull(struct vfp_ctx *ctx, struct vfp_entry *ent, void *ptr,
CHECK_OBJ_NOTNULL(ent, VFP_ENTRY_MAGIC);
AN(ent->vfp);
AN(ent->vfp->name);
CAST_OBJ_NOTNULL(settings, ent->vfp->priv1, VFP_SETTINGS_MAGIC);
vp = decrypt_init(ctx, ece, settings, ent->vfp->name);
CAST_OBJ_NOTNULL(cfg, ent->vfp->priv1, VFP_CFG_MAGIC);
vp = decrypt_init(ctx, ece, cfg, ent->vfp->name);
if (vp == VFP_ERROR)
return (vp);
if (vp == VFP_NULL) {
......@@ -343,10 +352,17 @@ static struct vfp_settings default_settings = {
.rs = DEFAULT_MAX_RS,
};
static struct vfp_cfg default_cfg = {
.magic = VFP_CFG_MAGIC,
.settings = &default_settings,
.stats = NULL,
.vsc_seg = NULL,
};
const struct vfp vfp_decrypt = {
.name = "ece_decrypt",
.init = vfp_decrypt_init,
.pull = vfp_decrypt_pull,
.fini = vfp_common_fini,
.priv1 = &default_settings,
.priv1 = &default_cfg,
};
......@@ -112,12 +112,15 @@ vfp_encrypt_init(struct vfp_ctx *ctx, struct vfp_entry *ent)
{
struct ece *ece = NULL;
struct ece_hdrbuf *hdrbuf;
const struct vfp_cfg *cfg;
const char *keyid;
size_t keyid_len;
char errmsg[ERRMSG_LEN];
CHECK_OBJ_NOTNULL(ctx, VFP_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ent, VFP_ENTRY_MAGIC);
AN(ent->vfp);
CAST_OBJ_NOTNULL(cfg, ent->vfp->priv1, VFP_CFG_MAGIC);
/* XXX implement me */
if (http_GetStatus(ctx->resp) == 206)
......@@ -126,6 +129,9 @@ vfp_encrypt_init(struct vfp_ctx *ctx, struct vfp_entry *ent)
if (http_GetHdr(ctx->resp, H_Content_Encoding, NULL))
return (VFP_NULL);
if (cfg->stats != NULL)
cfg->stats->ops++;
/* XXX make the key header configurable */
if (http_GetHdr(ctx->req, DEFAULT_KEY_HDR, &keyid) == 0)
return (VERR(ctx, "key id header %s not found",
......@@ -259,9 +265,21 @@ vfp_encrypt_pull(struct vfp_ctx *ctx, struct vfp_entry *ent, void *ptr,
return (vp);
}
static struct vfp_settings default_settings = {
.magic = VFP_SETTINGS_MAGIC,
};
static struct vfp_cfg default_cfg = {
.magic = VFP_CFG_MAGIC,
.settings = &default_settings,
.stats = NULL,
.vsc_seg = NULL,
};
const struct vfp vfp_encrypt = {
.name = "ece_encrypt",
.init = vfp_encrypt_init,
.pull = vfp_encrypt_pull,
.fini = vfp_common_fini,
.priv1 = &default_cfg,
};
......@@ -54,6 +54,7 @@ struct VPFX(ece_decrypter) {
#define ECE_DECRYPTER_MAGIC 0x2a28a833
char *vcl_name;
struct vfp *vfp;
struct vfp_cfg *cfg;
};
struct custom_vfp_entry {
......@@ -89,7 +90,7 @@ VPFX(event)(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
{
struct custom_vfp_head *vfph;
struct custom_vfp_entry *vfpe;
struct vfp_settings *settings;
struct vfp_cfg *cfg;
static int loaded = 0;
ASSERT_CLI();
......@@ -104,6 +105,17 @@ VPFX(event)(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
VRT_AddVFP(ctx, &vfp_encrypt);
VRT_AddVFP(ctx, &vfp_decrypt);
CAST_OBJ_NOTNULL(cfg, TRUST_ME(vfp_encrypt.priv1),
VFP_CFG_MAGIC);
if (cfg->stats == NULL)
cfg->stats = VSC_ece_New(NULL, &cfg->vsc_seg,
"vfp.ece_encrypt");
CAST_OBJ_NOTNULL(cfg, TRUST_ME(vfp_decrypt.priv1),
VFP_CFG_MAGIC);
if (cfg->stats == NULL)
cfg->stats = VSC_ece_New(NULL, &cfg->vsc_seg,
"vfp.ece_decrypt");
assert(loaded >= 0);
if (loaded++ == 0)
if (KEY_Init(ctx) != 0)
......@@ -117,15 +129,9 @@ VPFX(event)(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
vfpe = VSLIST_FIRST(vfph);
CHECK_OBJ_NOTNULL(vfpe, CUSTOM_VFP_MAGIC);
if (vfpe->vfp != NULL) {
if (vfpe->vfp->priv1 != NULL) {
CAST_OBJ(settings,
TRUST_ME(vfpe->vfp->priv1),
VFP_SETTINGS_MAGIC);
if (settings != NULL)
FREE_OBJ(settings);
}
VRT_RemoveVFP(ctx, vfpe->vfp);
free(vfpe->vfp);
/* cfg freed in object .fini */
}
VSLIST_REMOVE_HEAD(vfph, list);
FREE_OBJ(vfpe);
......@@ -133,8 +139,17 @@ VPFX(event)(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
free(vfph);
AN(loaded);
if (--loaded == 0)
if (--loaded == 0) {
KEY_Fini();
CAST_OBJ_NOTNULL(cfg, TRUST_ME(vfp_encrypt.priv1),
VFP_CFG_MAGIC);
if (cfg->vsc_seg != NULL)
VSC_ece_Destroy(&cfg->vsc_seg);
CAST_OBJ_NOTNULL(cfg, TRUST_ME(vfp_decrypt.priv1),
VFP_CFG_MAGIC);
if (cfg->vsc_seg != NULL)
VSC_ece_Destroy(&cfg->vsc_seg);
}
return (0);
case VCL_EVENT_WARM:
case VCL_EVENT_COLD:
......@@ -154,6 +169,7 @@ vmod_decrypter__init(VRT_CTX, struct VPFX(ece_decrypter) **decp,
{
struct VPFX(ece_decrypter) *dec;
struct vfp *vfp;
struct vfp_cfg *cfg;
struct vfp_settings *settings;
struct custom_vfp_head *vfph;
struct custom_vfp_entry *vfpe;
......@@ -230,6 +246,14 @@ vmod_decrypter__init(VRT_CTX, struct VPFX(ece_decrypter) **decp,
return;
}
errno = 0;
ALLOC_OBJ(cfg, VFP_CFG_MAGIC);
if (cfg == NULL) {
VFAIL(ctx, "new %s: cannot allocate space for config: %s",
vcl_name, vstrerror(errno));
return;
}
errno = 0;
ALLOC_OBJ(settings, VFP_SETTINGS_MAGIC);
if (settings == NULL) {
......@@ -237,6 +261,7 @@ vmod_decrypter__init(VRT_CTX, struct VPFX(ece_decrypter) **decp,
vcl_name, vstrerror(errno));
return;
}
cfg->settings = settings;
errno = 0;
ALLOC_OBJ(vfpe, CUSTOM_VFP_MAGIC);
......@@ -255,7 +280,7 @@ vmod_decrypter__init(VRT_CTX, struct VPFX(ece_decrypter) **decp,
vfp->init = vfp_decrypt_init;
vfp->pull = vfp_decrypt_pull;
vfp->fini = vfp_common_fini;
vfp->priv1 = settings;
vfp->priv1 = cfg;
VRT_AddVFP(ctx, vfp);
vfpe->vfp = vfp;
......@@ -274,12 +299,24 @@ vmod_decrypter__init(VRT_CTX, struct VPFX(ece_decrypter) **decp,
VCL_VOID vmod_decrypter__fini(struct VPFX(ece_decrypter) **decp)
{
struct VPFX(ece_decrypter) *dec;
struct vfp_cfg *cfg;
if (decp == NULL || *decp == NULL)
return;
TAKE_OBJ_NOTNULL(dec, decp, ECE_DECRYPTER_MAGIC);
if (dec->vcl_name != NULL)
free(dec->vcl_name);
if (dec->cfg != NULL) {
CHECK_OBJ(dec->cfg, VFP_CFG_MAGIC);
cfg = dec->cfg;
if (cfg->settings != NULL) {
CHECK_OBJ(cfg->settings, VFP_SETTINGS_MAGIC);
FREE_OBJ(cfg->settings);
}
if (cfg->vsc_seg != NULL)
VSC_ece_Destroy(&cfg->vsc_seg);
FREE_OBJ(cfg);
}
FREE_OBJ(dec);
}
......
Markdown is supported
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