Linux server.kiran-academy.com 3.10.0-1160.108.1.el7.x86_64 #1 SMP Thu Jan 25 16:17:31 UTC 2024 x86_64
Apache/2.4.57 (Unix) OpenSSL/1.0.2k-fips
: 194.233.91.196 | : 216.73.216.172
Cant Read [ /etc/named.conf ]
7.4.32
finalho
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
share /
doc /
varnish-5.2.1 /
html /
reference /
[ HOME SHELL ]
Name
Size
Permission
Action
directors.html
17.15
KB
-rw-r--r--
index.html
11.66
KB
-rw-r--r--
states.html
6.61
KB
-rw-r--r--
varnish-cli.html
42.86
KB
-rw-r--r--
varnish-counters.html
47.32
KB
-rw-r--r--
varnishadm.html
11.39
KB
-rw-r--r--
varnishd.html
97.37
KB
-rw-r--r--
varnishhist.html
13.74
KB
-rw-r--r--
varnishlog.html
14.57
KB
-rw-r--r--
varnishncsa.html
20.51
KB
-rw-r--r--
varnishstat.html
15.77
KB
-rw-r--r--
varnishtest.html
20.91
KB
-rw-r--r--
varnishtop.html
14.9
KB
-rw-r--r--
vcl.html
60.01
KB
-rw-r--r--
vmod.html
38.09
KB
-rw-r--r--
vmod_blob.generated.html
60.21
KB
-rw-r--r--
vmod_directors.generated.html
47.28
KB
-rw-r--r--
vmod_purge.generated.html
11.75
KB
-rw-r--r--
vmod_std.generated.html
36.32
KB
-rw-r--r--
vmod_vtc.generated.html
21.55
KB
-rw-r--r--
vsl-query.html
23.18
KB
-rw-r--r--
vsl.html
57.59
KB
-rw-r--r--
vsm.html
10.09
KB
-rw-r--r--
vtc.html
57.21
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : vmod.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>VMOD - Varnish Modules — Varnish version 5.2.1 documentation</title> <link rel="stylesheet" href="../_static/classic.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '5.2.1', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="index" title="Index" href="../genindex.html" /> <link rel="search" title="Search" href="../search.html" /> <link rel="top" title="Varnish version 5.2.1 documentation" href="../index.html" /> <link rel="up" title="The Varnish Reference Manual" href="index.html" /> <link rel="next" title="vmod_std" href="vmod_std.generated.html" /> <link rel="prev" title="VSM: Shared Memory Logging and Statistics" href="vsm.html" /> </head> <body role="document"> <div class="related" role="navigation" aria-label="related navigation"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="vmod_std.generated.html" title="vmod_std" accesskey="N">next</a> |</li> <li class="right" > <a href="vsm.html" title="VSM: Shared Memory Logging and Statistics" accesskey="P">previous</a> |</li> <li class="nav-item nav-item-0"><a href="../index.html">Varnish version 5.2.1 documentation</a> »</li> <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">The Varnish Reference Manual</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body" role="main"> <div class="section" id="vmod-varnish-modules"> <span id="ref-vmod"></span><h1>VMOD - Varnish Modules<a class="headerlink" href="#vmod-varnish-modules" title="Permalink to this headline">¶</a></h1> <p>For all you can do in VCL, there are things you can not do. Look an IP number up in a database file for instance. VCL provides for inline C code, and there you can do everything, but it is not a convenient or even readable way to solve such problems.</p> <p>This is where VMODs come into the picture: A VMOD is a shared library with some C functions which can be called from VCL code.</p> <p>For instance:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">std</span><span class="p">;</span> <span class="n">sub</span> <span class="n">vcl_deliver</span> <span class="p">{</span> <span class="nb">set</span> <span class="n">resp</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">foo</span> <span class="o">=</span> <span class="n">std</span><span class="o">.</span><span class="n">toupper</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">url</span><span class="p">);</span> <span class="p">}</span> </pre></div> </div> <p>The "std" vmod is one you get with Varnish, it will always be there and we will put "boutique" functions in it, such as the "toupper" function shown above. The full contents of the "std" module is documented in vmod_std(3).</p> <p>This part of the manual is about how you go about writing your own VMOD, how the language interface between C and VCC works, where you can find contributed VMODs etc. This explanation will use the "std" VMOD as example, having a Varnish source tree handy may be a good idea.</p> <div class="section" id="vmod-directory"> <h2>VMOD Directory<a class="headerlink" href="#vmod-directory" title="Permalink to this headline">¶</a></h2> <p>The VMOD directory is an up-to-date compilation of maintained extensions written for Varnish Cache:</p> <blockquote> <div><a class="reference external" href="https://www.varnish-cache.org/vmods">https://www.varnish-cache.org/vmods</a></div></blockquote> </div> <div class="section" id="the-vmod-vcc-file"> <h2>The vmod.vcc file<a class="headerlink" href="#the-vmod-vcc-file" title="Permalink to this headline">¶</a></h2> <p>The interface between your VMOD and the VCL compiler ("VCC") and the VCL runtime ("VRT") is defined in the vmod.vcc file which a python script called "vmodtool.py" turns into thaumaturgically challenged C data structures that does all the hard work.</p> <p>The std VMODs vmod.vcc file looks somewhat like this:</p> <div class="highlight-default"><div class="highlight"><pre><span></span>$Module std 3 $Event event_function $Function STRING toupper(STRING_LIST) $Function STRING tolower(STRING_LIST) $Function VOID set_ip_tos(INT) </pre></div> </div> <p>The first line gives the name of the module and the manual section where the documentation will reside.</p> <p>The second line specifies an optional "Event" function, which will be called whenever a VCL program which imports this VMOD is loaded or transitions to any of the warm, active, cold or discarded states. More on this below.</p> <p>The next three lines define three functions in the VMOD, along with the types of the arguments, and that is probably where the hardest bit of writing a VMOD is to be found, so we will talk about that at length in a moment.</p> <p>Notice that the third function returns VOID, that makes it a "procedure" in VCL lingo, meaning that it cannot be used in expressions, right side of assignments and such. Instead it can be used as a primary action, something functions which return a value can not:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">sub</span> <span class="n">vcl_recv</span> <span class="p">{</span> <span class="n">std</span><span class="o">.</span><span class="n">set_ip_tos</span><span class="p">(</span><span class="mi">32</span><span class="p">);</span> <span class="p">}</span> </pre></div> </div> <p>Running vmodtool.py on the vmod.vcc file, produces a "vcc_if.c" and "vcc_if.h" files, which you must use to build your shared library file.</p> <p>Forget about vcc_if.c everywhere but your Makefile, you will never need to care about its contents, and you should certainly never modify it, that voids your warranty instantly.</p> <p>But vcc_if.h is important for you, it contains the prototypes for the functions you want to export to VCL.</p> <p>For the std VMOD, the compiled vcc_if.h file looks like this:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">struct</span> <span class="n">vmod_priv</span><span class="p">;</span> <span class="n">VCL_STRING</span> <span class="n">vmod_toupper</span><span class="p">(</span><span class="n">VRT_CTX</span><span class="p">,</span> <span class="n">const</span> <span class="n">char</span> <span class="o">*</span><span class="p">,</span> <span class="o">...</span><span class="p">);</span> <span class="n">VCL_STRING</span> <span class="n">vmod_tolower</span><span class="p">(</span><span class="n">VRT_CTX</span><span class="p">,</span> <span class="n">const</span> <span class="n">char</span> <span class="o">*</span><span class="p">,</span> <span class="o">...</span><span class="p">);</span> <span class="n">VCL_VOID</span> <span class="n">vmod_set_ip_tos</span><span class="p">(</span><span class="n">VRT_CTX</span><span class="p">,</span> <span class="n">VCL_INT</span><span class="p">);</span> <span class="n">vmod_event_f</span> <span class="n">event_function</span><span class="p">;</span> </pre></div> </div> <p>Those are your C prototypes. Notice the <code class="docutils literal"><span class="pre">vmod_</span></code> prefix on the function names.</p> <div class="section" id="named-arguments-and-default-values"> <h3>Named arguments and default values<a class="headerlink" href="#named-arguments-and-default-values" title="Permalink to this headline">¶</a></h3> <p>The basic vmod.vcc function declaration syntax introduced above makes all arguments mandatory for calls from vcl - which implies that they need to be given in order.</p> <p>Naming the arguments as in:</p> <div class="highlight-default"><div class="highlight"><pre><span></span>$Function BOOL match_acl(ACL acl, IP ip) </pre></div> </div> <p>allows calls from VCL with named arguments in any order, for example:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">debug</span><span class="o">.</span><span class="n">match_acl</span><span class="p">(</span><span class="n">ip</span><span class="o">=</span><span class="n">client</span><span class="o">.</span><span class="n">ip</span><span class="p">,</span> <span class="n">acl</span><span class="o">=</span><span class="n">local</span><span class="p">))</span> <span class="p">{</span> <span class="c1"># ...</span> </pre></div> </div> <p>Named arguments also take default values, so for this example from the debug vmod:</p> <div class="highlight-default"><div class="highlight"><pre><span></span>$Function STRING argtest(STRING one, REAL two=2, STRING three="3", STRING comma=",", INT four=4) </pre></div> </div> <p>only argument <cite>one</cite> is required, so that all of the following are valid invocations from vcl:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">debug</span><span class="o">.</span><span class="n">argtest</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="mf">2.1</span><span class="p">,</span> <span class="s2">"3a"</span><span class="p">)</span> <span class="n">debug</span><span class="o">.</span><span class="n">argtest</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="n">two</span><span class="o">=</span><span class="mf">2.2</span><span class="p">,</span> <span class="n">three</span><span class="o">=</span><span class="s2">"3b"</span><span class="p">)</span> <span class="n">debug</span><span class="o">.</span><span class="n">argtest</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="n">three</span><span class="o">=</span><span class="s2">"3c"</span><span class="p">,</span> <span class="n">two</span><span class="o">=</span><span class="mf">2.3</span><span class="p">)</span> <span class="n">debug</span><span class="o">.</span><span class="n">argtest</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="mf">2.4</span><span class="p">,</span> <span class="n">three</span><span class="o">=</span><span class="s2">"3d"</span><span class="p">)</span> <span class="n">debug</span><span class="o">.</span><span class="n">argtest</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="mf">2.5</span><span class="p">)</span> <span class="n">debug</span><span class="o">.</span><span class="n">argtest</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="n">four</span><span class="o">=</span><span class="mi">6</span><span class="p">);</span> </pre></div> </div> <p>The C interface does not change with named arguments and default values, arguments remain positional and defaul values appear no different to user specified values.</p> <p><cite>Note</cite> that default values have to be given in the native C-type syntax, see below. As a special case, <code class="docutils literal"><span class="pre">NULL</span></code> has to be given as <code class="docutils literal"><span class="pre">0</span></code>.</p> </div> </div> <div class="section" id="vcl-and-c-data-types"> <span id="ref-vmod-vcl-c-types"></span><h2>VCL and C data types<a class="headerlink" href="#vcl-and-c-data-types" title="Permalink to this headline">¶</a></h2> <p>VCL data types are targeted at the job, so for instance, we have data types like "DURATION" and "HEADER", but they all have some kind of C language representation. Here is a description of them.</p> <p>All but the PRIV and STRING_LIST types have typedefs: VCL_INT, VCL_REAL, etc.</p> <dl class="docutils"> <dt>ACL</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">vrt_acl</span> <span class="pre">*</span></code></p> <p class="last">A type for named ACLs declared in VCL.</p> </dd> <dt>BACKEND</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">director</span> <span class="pre">*</span></code></p> <p class="last">A type for backend and director implementations. See <a class="reference internal" href="directors.html#ref-writing-a-director"><span class="std std-ref">Writing a Director</span></a>.</p> </dd> <dt>BLOB</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">vmod_priv</span> <span class="pre">*</span></code></p> <p class="last">An opaque type to pass random bits of memory between VMOD functions.</p> </dd> <dt>BOOL</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">unsigned</span></code></p> <p class="last">Zero means false, anything else means true.</p> </dd> <dt>BYTES</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">double</span></code></p> <p>Unit: bytes.</p> <p class="last">A storage space, as in 1024 bytes.</p> </dd> <dt>DURATION</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">double</span></code></p> <p>Unit: seconds.</p> <p class="last">A time interval, as in 25 seconds.</p> </dd> <dt>ENUM</dt> <dd><p class="first">vcc syntax: ENUM { val1, val2, ... }</p> <p>vcc example: <code class="docutils literal"><span class="pre">ENUM</span> <span class="pre">{</span> <span class="pre">one,</span> <span class="pre">two,</span> <span class="pre">three</span> <span class="pre">}</span> <span class="pre">number="one"</span></code></p> <p>C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></code></p> <p class="last">Allows values from a set of constant strings. <cite>Note</cite> that the C-type is a string, not a C enum.</p> </dd> <dt>HEADER</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">gethdr_s</span> <span class="pre">*</span></code></p> <p>These are VCL compiler generated constants referencing a particular header in a particular HTTP entity, for instance <code class="docutils literal"><span class="pre">req.http.cookie</span></code> or <code class="docutils literal"><span class="pre">beresp.http.last-modified</span></code>. By passing a reference to the header, the VMOD code can both read and write the header in question.</p> <p class="last">If the header was passed as STRING, the VMOD code only sees the value, but not where it came from.</p> </dd> <dt>HTTP</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">struct</span> <span class="pre">http</span> <span class="pre">*</span></code></p> <p class="last">TODO</p> </dd> <dt>INT</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">long</span></code></p> <p class="last">A (long) integer as we know and love them.</p> </dd> <dt>IP</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">suckaddr</span> <span class="pre">*</span></code></p> <p class="last">This is an opaque type, see the <code class="docutils literal"><span class="pre">include/vsa.h</span></code> file for which primitives we support on this type.</p> </dd> <dt>PRIV_CALL</dt> <dd>See <a class="reference internal" href="#ref-vmod-private-pointers"><span class="std std-ref">Private Pointers</span></a> below.</dd> <dt>PRIV_TASK</dt> <dd>See <a class="reference internal" href="#ref-vmod-private-pointers"><span class="std std-ref">Private Pointers</span></a> below.</dd> <dt>PRIV_TOP</dt> <dd>See <a class="reference internal" href="#ref-vmod-private-pointers"><span class="std std-ref">Private Pointers</span></a> below.</dd> <dt>PRIV_VCL</dt> <dd>See <a class="reference internal" href="#ref-vmod-private-pointers"><span class="std std-ref">Private Pointers</span></a> below.</dd> <dt>PROBE</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">vrt_backend_probe</span> <span class="pre">*</span></code></p> <p class="last">A named standalone backend probe definition.</p> </dd> <dt>REAL</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">double</span></code></p> <p class="last">A floating point value.</p> </dd> <dt>STRING</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></code></p> <p>A NUL-terminated text-string.</p> <p>Can be NULL to indicate a nonexistent string, for instance in:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">mymod</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">foobar</span><span class="p">);</span> </pre></div> </div> <p>If there were no "foobar" HTTP header, the vmod_foo() function would be passed a NULL pointer as argument.</p> <p class="last">When used as a return value, the producing function is responsible for arranging memory management. Either by freeing the string later by whatever means available or by using storage allocated from the client or backend workspaces.</p> </dd> <dt>STEVEDORE</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">struct</span> <span class="pre">stevedore</span> <span class="pre">*</span></code></p> <p class="last">A storage backend.</p> </dd> <dt>STRING_LIST</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*,</span> <span class="pre">...</span></code></p> <p>A multi-component text-string. We try very hard to avoid doing text-processing in Varnish, and this is one way we to avoid that, by not editing separate pieces of a string together to one string, unless we have to.</p> <p>Consider this contrived example:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="nb">set</span> <span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">foo</span> <span class="o">=</span> <span class="n">std</span><span class="o">.</span><span class="n">toupper</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">foo</span> <span class="o">+</span> <span class="n">req</span><span class="o">.</span><span class="n">http</span><span class="o">.</span><span class="n">bar</span><span class="p">);</span> </pre></div> </div> <p>The usual way to do this, would be be to allocate memory for the concatenated string, then pass that to <code class="docutils literal"><span class="pre">toupper()</span></code> which in turn would return another freshly allocated string with the modified result. Remember: strings in VCL are <code class="docutils literal"><span class="pre">const</span></code>, we cannot just modify the string in place.</p> <p>What we do instead, is declare that <code class="docutils literal"><span class="pre">toupper()</span></code> takes a "STRING_LIST" as argument. This makes the C function implementing <code class="docutils literal"><span class="pre">toupper()</span></code> a vararg function (see the prototype above) and responsible for considering all the <code class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></code> arguments it finds, until the magic marker "vrt_magic_string_end" is encountered.</p> <p>Bear in mind that the individual strings in a STRING_LIST can be NULL, as described under STRING, that is why we do not use NULL as the terminator.</p> <p>Right now we only support STRING_LIST being the last argument to a function, we may relax that at a latter time.</p> <p class="last">If you don't want to bother with STRING_LIST, just use STRING and make sure your workspace_client and workspace_backend params are big enough.</p> </dd> <dt>TIME</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">double</span></code></p> <p>Unit: seconds since UNIX epoch.</p> <p class="last">An absolute time, as in 1284401161.</p> </dd> <dt>VOID</dt> <dd><p class="first">C-type: <code class="docutils literal"><span class="pre">void</span></code></p> <p class="last">Can only be used for return-value, which makes the function a VCL procedure.</p> </dd> </dl> </div> <div class="section" id="private-pointers"> <span id="ref-vmod-private-pointers"></span><h2>Private Pointers<a class="headerlink" href="#private-pointers" title="Permalink to this headline">¶</a></h2> <p>It is often useful for library functions to maintain local state, this can be anything from a precompiled regexp to open file descriptors and vast data structures.</p> <p>The VCL compiler supports the following private pointers:</p> <ul class="simple"> <li><code class="docutils literal"><span class="pre">PRIV_CALL</span></code> "per call" private pointers are useful to cache/store state relative to the specific call or its arguments, for instance a compiled regular expression specific to a regsub() statement or a simply caching the last output of some expensive lookup.</li> <li><code class="docutils literal"><span class="pre">PRIV_TASK</span></code> "per task" private pointers are useful for state that applies to calls for either a specific request or a backend request. For instance this can be the result of a parsed cookie specific to a client. Note that <code class="docutils literal"><span class="pre">PRIV_TASK</span></code> contexts are separate for the client side and the backend side, so use in <code class="docutils literal"><span class="pre">vcl_backend_*</span></code> will yield a different private pointer from the one used on the client side.</li> <li><code class="docutils literal"><span class="pre">PRIV_TOP</span></code> "per top-request" private pointers live for the duration of one request and all its ESI-includes. They are only defined for the client side. When used from backend VCL subs, a NULL pointer will be passed.</li> <li><code class="docutils literal"><span class="pre">PRIV_VCL</span></code> "per vcl" private pointers are useful for such global state that applies to all calls in this VCL, for instance flags that determine if regular expressions are case-sensitive in this vmod or similar. The <code class="docutils literal"><span class="pre">PRIV_VCL</span></code> object is the same object that is passed to the VMOD's event function.</li> </ul> <p>The way it works in the vmod code, is that a <code class="docutils literal"><span class="pre">struct</span> <span class="pre">vmod_priv</span> <span class="pre">*</span></code> is passed to the functions where one of the <code class="docutils literal"><span class="pre">PRIV_*</span></code> argument types is specified.</p> <p>This structure contains three members:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">typedef</span> <span class="n">void</span> <span class="n">vmod_priv_free_f</span><span class="p">(</span><span class="n">void</span> <span class="o">*</span><span class="p">);</span> <span class="n">struct</span> <span class="n">vmod_priv</span> <span class="p">{</span> <span class="n">void</span> <span class="o">*</span><span class="n">priv</span><span class="p">;</span> <span class="nb">int</span> <span class="nb">len</span><span class="p">;</span> <span class="n">vmod_priv_free_f</span> <span class="o">*</span><span class="n">free</span><span class="p">;</span> <span class="p">};</span> </pre></div> </div> <p>The "priv" element can be used for whatever the vmod code wants to use it for, it defaults to a NULL pointer.</p> <p>The "len" element is used primarily for BLOBs to indicate its size.</p> <p>The "free" element defaults to NULL, and it is the modules responsibility to set it to a suitable function, which can clean up whatever the "priv" pointer points to.</p> <p>When a VCL program is discarded, all private pointers are checked to see if both the "priv" and "free" elements are non-NULL, and if they are, the "free" function will be called with the "priv" pointer as the only argument.</p> <p>In the common case where a private data structure is allocated with malloc would look like this:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">priv</span><span class="o">-></span><span class="n">priv</span> <span class="o">==</span> <span class="n">NULL</span><span class="p">)</span> <span class="p">{</span> <span class="n">priv</span><span class="o">-></span><span class="n">priv</span> <span class="o">=</span> <span class="n">calloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">sizeof</span><span class="p">(</span><span class="n">struct</span> <span class="n">myfoo</span><span class="p">));</span> <span class="n">AN</span><span class="p">(</span><span class="n">priv</span><span class="o">-></span><span class="n">priv</span><span class="p">);</span> <span class="n">priv</span><span class="o">-></span><span class="n">free</span> <span class="o">=</span> <span class="n">free</span><span class="p">;</span> <span class="o">/*</span> <span class="n">free</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">*/</span> <span class="n">mystate</span> <span class="o">=</span> <span class="n">priv</span><span class="o">-></span><span class="n">priv</span><span class="p">;</span> <span class="n">mystate</span><span class="o">-></span><span class="n">foo</span> <span class="o">=</span> <span class="mi">21</span><span class="p">;</span> <span class="o">...</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">mystate</span> <span class="o">=</span> <span class="n">priv</span><span class="o">-></span><span class="n">priv</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">foo</span> <span class="o">></span> <span class="mi">25</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span> </pre></div> </div> <p>The per-call vmod_privs are freed before the per-vcl vmod_priv.</p> </div> <div class="section" id="event-functions"> <span id="ref-vmod-event-functions"></span><h2>Event functions<a class="headerlink" href="#event-functions" title="Permalink to this headline">¶</a></h2> <p>VMODs can have an "event" function which is called when a VCL which imports the VMOD is loaded or discarded. This corresponds to the <code class="docutils literal"><span class="pre">VCL_EVENT_LOAD</span></code> and <code class="docutils literal"><span class="pre">VCL_EVENT_DISCARD</span></code> events, respectively. In addition, this function will be called when the VCL temperature is changed to cold or warm, corresponding to the <code class="docutils literal"><span class="pre">VCL_EVENT_COLD</span></code> and <code class="docutils literal"><span class="pre">VCL_EVENT_WARM</span></code> events.</p> <p>The first argument to the event function is a VRT context.</p> <p>The second argument is the vmod_priv specific to this particular VCL, and if necessary, a VCL specific VMOD "fini" function can be attached to its "free" hook.</p> <p>The third argument is the event.</p> <p>If the VMOD has private global state, which includes any sockets or files opened, any memory allocated to global or private variables in the C-code etc, it is the VMODs own responsibility to track how many VCLs were loaded or discarded and free this global state when the count reaches zero.</p> <p>VMOD writers are <em>strongly</em> encouraged to release all per-VCL resources for a given VCL when it emits a <code class="docutils literal"><span class="pre">VCL_EVENT_COLD</span></code> event. You will get a chance to reacquire the resources before the VCL becomes active again and be notified first with a <code class="docutils literal"><span class="pre">VCL_EVENT_WARM</span></code> event. Unless a user decides that a given VCL should always be warm, an inactive VMOD will eventually become cold and should manage resources accordingly.</p> <p>An event function must return zero upon success. It is only possible to fail an initialization with the <code class="docutils literal"><span class="pre">VCL_EVENT_LOAD</span></code> or <code class="docutils literal"><span class="pre">VCL_EVENT_WARM</span></code> events. Should such a failure happen, a <code class="docutils literal"><span class="pre">VCL_EVENT_DISCARD</span></code> or <code class="docutils literal"><span class="pre">VCL_EVENT_COLD</span></code> event will be sent to the VMODs that succeeded to put them back in a cold state. The VMOD that failed will not receive this event, and therefore must not be left half-initialized should a failure occur.</p> <p>If your VMOD is running an asynchronous background job you can hold a reference to the VCL to prevent it from going cold too soon and get the same guarantees as backends with ongoing requests for instance. For that, you must acquire the reference by calling <code class="docutils literal"><span class="pre">VRT_ref_vcl</span></code> when you receive a <code class="docutils literal"><span class="pre">VCL_EVENT_WARM</span></code> and later calling <code class="docutils literal"><span class="pre">VRT_rel_vcl</span></code> once the background job is over. Receiving a <code class="docutils literal"><span class="pre">VCL_EVENT_COLD</span></code> is your cue to terminate any background job bound to a VCL.</p> <p>You can find an example of VCL references in vmod-debug:</p> <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">priv_vcl</span><span class="o">-></span><span class="n">vclref</span> <span class="o">=</span> <span class="n">VRT_ref_vcl</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s2">"vmod-debug"</span><span class="p">);</span> <span class="o">...</span> <span class="n">VRT_rel_vcl</span><span class="p">(</span><span class="o">&</span><span class="n">ctx</span><span class="p">,</span> <span class="o">&</span><span class="n">priv_vcl</span><span class="o">-></span><span class="n">vclref</span><span class="p">);</span> </pre></div> </div> <p>In this simplified version, you can see that you need at least a VCL-bound data structure like a <code class="docutils literal"><span class="pre">PRIV_VCL</span></code> or a VMOD object to keep track of the reference and later release it. You also have to provide a description, it will be printed to the user if they try to warm up a cooling VCL:</p> <div class="highlight-default"><div class="highlight"><pre><span></span>$ varnishadm vcl.list available auto/cooling 0 vcl1 active auto/warm 0 vcl2 $ varnishadm vcl.state vcl1 warm Command failed with error code 300 Failed <vcl.state vcl1 auto> Message: VCL vcl1 is waiting for: - vmod-debug </pre></div> </div> <p>In the case where properly releasing resources may take some time, you can opt for an asynchronous worker, either by spawning a thread and tracking it, or by using Varnish's worker pools.</p> </div> <div class="section" id="when-to-lock-and-when-not-to-lock"> <h2>When to lock, and when not to lock<a class="headerlink" href="#when-to-lock-and-when-not-to-lock" title="Permalink to this headline">¶</a></h2> <p>Varnish is heavily multithreaded, so by default VMODs must implement their own locking to protect shared resources.</p> <p>When a VCL is loaded or unloaded, the event and priv->free are run sequentially all in a single thread, and there is guaranteed to be no other activity related to this particular VCL, nor are there init/fini activity in any other VCL or VMOD at this time.</p> <p>That means that the VMOD init, and any object init/fini functions are already serialized in sensible order, and won't need any locking, unless they access VMOD specific global state, shared with other VCLs.</p> <p>Traffic in other VCLs which also import this VMOD, will be happening while housekeeping is going on.</p> </div> <div class="section" id="updating-vmods"> <h2>Updating VMODs<a class="headerlink" href="#updating-vmods" title="Permalink to this headline">¶</a></h2> <p>A compiled VMOD is a shared library file which Varnish dlopen(3)'s using flags RTLD_NOW | RTLD_LOCAL.</p> <p>As a general rule, once a file is opened with dlopen(3) you should never modify it, but it is safe to rename it and put a new file under the name it had, which is how most tools installs and updates shared libraries.</p> <p>However, when you call dlopen(3) with the same filename multiple times it will give you the same single copy of the shared library file, without checking if it was updated in the meantime.</p> <p>This is obviously an oversight in the design of the dlopen(3) library function, but back in the late 1980s nobody could imagine why a program would ever want to have multiple different versions of the same shared library mapped at the same time.</p> <p>Varnish does that, and therefore you must restart the worker process before Varnish will discover an updated VMOD.</p> <p>If you want to test a new version of a VMOD, while being able to instantly switch back to the old version, you will have to install each version with a distinct filename or in a distinct subdirectory and use <code class="docutils literal"><span class="pre">import</span> <span class="pre">foo</span> <span class="pre">from</span> <span class="pre">"...";</span></code> to reference it in your VCL.</p> <p>We're not happy about this, but have found no sensible workarounds.</p> </div> </div> </div> </div> </div> <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> <div class="sphinxsidebarwrapper"> <h3><a href="../index.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">VMOD - Varnish Modules</a><ul> <li><a class="reference internal" href="#vmod-directory">VMOD Directory</a></li> <li><a class="reference internal" href="#the-vmod-vcc-file">The vmod.vcc file</a><ul> <li><a class="reference internal" href="#named-arguments-and-default-values">Named arguments and default values</a></li> </ul> </li> <li><a class="reference internal" href="#vcl-and-c-data-types">VCL and C data types</a></li> <li><a class="reference internal" href="#private-pointers">Private Pointers</a></li> <li><a class="reference internal" href="#event-functions">Event functions</a></li> <li><a class="reference internal" href="#when-to-lock-and-when-not-to-lock">When to lock, and when not to lock</a></li> <li><a class="reference internal" href="#updating-vmods">Updating VMODs</a></li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="vsm.html" title="previous chapter">VSM: Shared Memory Logging and Statistics</a></p> <h4>Next topic</h4> <p class="topless"><a href="vmod_std.generated.html" title="next chapter">vmod_std</a></p> <div role="note" aria-label="source link"> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/reference/vmod.txt" rel="nofollow">Show Source</a></li> </ul> </div> <div id="searchbox" style="display: none" role="search"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <div><input type="text" name="q" /></div> <div><input type="submit" value="Go" /></div> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related" role="navigation" aria-label="related navigation"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="vmod_std.generated.html" title="vmod_std" >next</a> |</li> <li class="right" > <a href="vsm.html" title="VSM: Shared Memory Logging and Statistics" >previous</a> |</li> <li class="nav-item nav-item-0"><a href="../index.html">Varnish version 5.2.1 documentation</a> »</li> <li class="nav-item nav-item-1"><a href="index.html" >The Varnish Reference Manual</a> »</li> </ul> </div> <div class="footer" role="contentinfo"> © Copyright 2010-2014, Varnish Software AS. Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.4.9. </div> </body> </html>
Close