varnish-cache/lib/libvmod_directors/hash.c
1
/*-
2
 * Copyright (c) 2013-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@FreeBSD.org>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
29
#include "config.h"
30
31
#include <stdlib.h>
32
#include <string.h>
33
34
#include "cache/cache.h"
35
#include "cache/cache_director.h"
36
37
#include "vend.h"
38
#include "vsha256.h"
39
40
#include "vdir.h"
41
42
#include "vcc_if.h"
43
44
struct vmod_directors_hash {
45
        unsigned                                magic;
46
#define VMOD_DIRECTORS_HASH_MAGIC               0xc08dd611
47
        struct vdir                             *vd;
48
};
49
50
VCL_VOID v_matchproto_()
51 2
vmod_hash__init(VRT_CTX, struct vmod_directors_hash **rrp,
52
    const char *vcl_name)
53
{
54
        struct vmod_directors_hash *rr;
55
56 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
57 2
        AN(rrp);
58 2
        AZ(*rrp);
59 2
        ALLOC_OBJ(rr, VMOD_DIRECTORS_HASH_MAGIC);
60 2
        AN(rr);
61 2
        *rrp = rr;
62 2
        vdir_new(&rr->vd, "hash", vcl_name, NULL, NULL, rr);
63 2
}
64
65
VCL_VOID v_matchproto_()
66 1
vmod_hash__fini(struct vmod_directors_hash **rrp)
67
{
68
        struct vmod_directors_hash *rr;
69
70 1
        rr = *rrp;
71 1
        *rrp = NULL;
72 1
        CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
73 1
        vdir_delete(&rr->vd);
74 1
        FREE_OBJ(rr);
75 1
}
76
77
VCL_VOID v_matchproto_()
78 3
vmod_hash_add_backend(VRT_CTX,
79
    struct vmod_directors_hash *rr, VCL_BACKEND be, double w)
80
{
81
82 3
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
83 3
        CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
84 3
        vdir_add_backend(ctx, rr->vd, be, w);
85 3
}
86
87
VCL_VOID v_matchproto_()
88 1
vmod_hash_remove_backend(VRT_CTX,
89
    struct vmod_directors_hash *rr, VCL_BACKEND be)
90
{
91
92 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
93 1
        CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
94 1
        vdir_remove_backend(ctx, rr->vd, be, NULL);
95 1
}
96
97
VCL_BACKEND v_matchproto_()
98 12
vmod_hash_backend(VRT_CTX, struct vmod_directors_hash *rr,
99
    const char *arg, ...)
100
{
101
        struct VSHA256Context sha_ctx;
102
        va_list ap;
103
        const char *p;
104
        unsigned char sha256[VSHA256_LEN];
105
        VCL_BACKEND be;
106
        double r;
107
108 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
109 12
        CHECK_OBJ_ORNULL(ctx->bo, BUSYOBJ_MAGIC);
110
111 12
        CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
112 12
        VSHA256_Init(&sha_ctx);
113 12
        va_start(ap, arg);
114 12
        p = arg;
115 38
        while (p != vrt_magic_string_end) {
116 14
                if (p != NULL && *p != '\0')
117 10
                        VSHA256_Update(&sha_ctx, p, strlen(p));
118 14
                p = va_arg(ap, const char *);
119
        }
120 12
        va_end(ap);
121 12
        VSHA256_Final(sha256, &sha_ctx);
122
123 12
        r = vbe32dec(sha256);
124 12
        r = scalbn(r, -32);
125 12
        assert(r >= 0 && r <= 1.0);
126 12
        be = vdir_pick_be(rr->vd, r, ctx->bo);
127 12
        return (be);
128
}