Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-ece
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
libvmod-ece
Commits
e2f0680a
Commit
e2f0680a
authored
Sep 18, 2019
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start addings stats, beginning with the ops counters for default VFPs.
parent
a2871806
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
170 additions
and
19 deletions
+170
-19
configure.ac
configure.ac
+1
-0
Makefile.am
src/Makefile.am
+9
-2
ece.vsc
src/ece.vsc
+15
-0
00basic.vtc
src/tests/00basic.vtc
+12
-0
decrypt.vtc
src/tests/decrypt.vtc
+20
-0
encrypt.vtc
src/tests/encrypt.vtc
+4
-0
encrypt_err.vtc
src/tests/encrypt_err.vtc
+8
-0
roundtrip.vtc
src/tests/roundtrip.vtc
+3
-0
vfp.h
src/vfp.h
+10
-0
vfp_decrypt.c
src/vfp_decrypt.c
+23
-7
vfp_encrypt.c
src/vfp_encrypt.c
+18
-0
vmod_ece.c
src/vmod_ece.c
+47
-10
No files found.
configure.ac
View file @
e2f0680a
...
...
@@ -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)
...
...
src/Makefile.am
View file @
e2f0680a
...
...
@@ -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
src/ece.vsc
0 → 100644
View file @
e2f0680a
..
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
src/tests/00basic.vtc
View file @
e2f0680a
...
...
@@ -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
src/tests/decrypt.vtc
View file @
e2f0680a
...
...
@@ -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
src/tests/encrypt.vtc
View file @
e2f0680a
...
...
@@ -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
src/tests/encrypt_err.vtc
View file @
e2f0680a
...
...
@@ -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
src/tests/roundtrip.vtc
View file @
e2f0680a
...
...
@@ -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
src/vfp.h
View file @
e2f0680a
...
...
@@ -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
);
...
...
src/vfp_decrypt.c
View file @
e2f0680a
...
...
@@ -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
,
};
src/vfp_encrypt.c
View file @
e2f0680a
...
...
@@ -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
,
};
src/vmod_ece.c
View file @
e2f0680a
...
...
@@ -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
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment