varnish-cache/lib/libvmod_std/vmod_std_conversions.c
1
/*-
2
 * Copyright (c) 2010-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
30
#include "config.h"
31
32
#include <ctype.h>
33
#include <limits.h>
34
#include <string.h>
35
#include <stdlib.h>
36
#include <sys/socket.h>
37
38
#include <netdb.h>
39
40
#include "cache/cache.h"
41
42
#include "vnum.h"
43
#include "vsa.h"
44
#include "vtim.h"
45
#include "vcc_if.h"
46
47
VCL_DURATION v_matchproto_(td_std_duration)
48 14
vmod_duration(VRT_CTX, VCL_STRING p, VCL_DURATION d)
49
{
50 14
        double r = VNUM_duration(p);
51
52
        (void) ctx;
53
54 14
        return (isnan(r) ? d : r);
55
}
56
57
VCL_INT v_matchproto_(td_std_integer)
58 266
vmod_integer(VRT_CTX, VCL_STRING p, VCL_INT i)
59
{
60
        const char *e;
61
        double r;
62
63 266
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
64
65 266
        if (p == NULL)
66 0
                return (i);
67
68 266
        r = VNUMpfx(p, &e);
69 266
        if (isnan(r) || e != NULL)
70 5
                return (i);
71
72 261
        r = trunc(r);
73 261
        if (r > LONG_MAX || r < LONG_MIN)
74 0
                return (i);
75
76 261
        return ((VCL_INT)r);
77
}
78
79
VCL_IP
80 18
vmod_ip(VRT_CTX, VCL_STRING s, VCL_IP d, VCL_BOOL n)
81
{
82 18
        struct addrinfo hints, *res0 = NULL;
83
        const struct addrinfo *res;
84
        int error;
85
        void *p;
86
        const struct suckaddr *r;
87
88 18
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
89 18
        AN(d);
90 18
        assert(VSA_Sane(d));
91
92 18
        p = WS_Alloc(ctx->ws, vsa_suckaddr_len);
93 18
        if (p == NULL) {
94 0
                VSLb(ctx->vsl, SLT_VCL_Error,
95
                    "vmod std.ip(): insufficient workspace");
96 0
                return (d);
97
        }
98 18
        r = NULL;
99
100 18
        if (s != NULL) {
101 18
                memset(&hints, 0, sizeof(hints));
102 18
                hints.ai_family = PF_UNSPEC;
103 18
                hints.ai_socktype = SOCK_STREAM;
104 18
                if (!n)
105 2
                        hints.ai_flags |= AI_NUMERICHOST;
106 18
                error = getaddrinfo(s, "80", &hints, &res0);
107 18
                if (!error) {
108 8
                        for (res = res0; res != NULL; res = res->ai_next) {
109 7
                                r = VSA_Build(p, res->ai_addr, res->ai_addrlen);
110 7
                                if (r != NULL)
111 6
                                        break;
112
                        }
113
                }
114
        }
115 18
        if (r == NULL) {
116 12
                WS_Reset(ctx->ws, (uintptr_t)p);
117 12
                r = d;
118
        }
119 18
        if (res0 != NULL)
120 7
                freeaddrinfo(res0);
121 18
        return (r);
122
}
123
124
VCL_REAL v_matchproto_(td_std_real)
125 60
vmod_real(VRT_CTX, VCL_STRING p, VCL_REAL d)
126
{
127
        double r;
128
129 60
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
130
131 60
        if (p == NULL)
132 3
                return (d);
133
134 57
        r = VNUM(p);
135
136 57
        if (isnan(r))
137 39
                return (d);
138
139 18
        return (r);
140
}
141
142
VCL_INT v_matchproto_(td_std_real2integer)
143 4
vmod_real2integer(VRT_CTX, VCL_REAL r, VCL_INT i)
144
{
145 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
146
147 4
        if (!isfinite(r))
148 0
                return (i);
149 4
        r = round(r);
150 4
        if (r > LONG_MAX || r < LONG_MIN)
151 2
                return(i);
152 2
        return ((VCL_INT)r);
153
}
154
155
VCL_TIME v_matchproto_(td_std_real2time)
156 5
vmod_real2time(VRT_CTX, VCL_REAL r, VCL_TIME t)
157
{
158 5
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
159
160 5
        if (!isfinite(r))
161 0
                return (t);
162
163 5
        return (r);
164
}
165
166
VCL_INT v_matchproto_(td_std_time2integer)
167 2
vmod_time2integer(VRT_CTX, VCL_TIME t, VCL_INT i)
168
{
169 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
170
171 2
        if (!isfinite(t))
172 0
                return (i);
173 2
        t = round(t);
174 2
        if (t > LONG_MAX || t < LONG_MIN)
175 0
                return(i);
176 2
        return ((VCL_INT)t);
177
}
178
179
VCL_REAL v_matchproto_(td_std_time2real)
180 2
vmod_time2real(VRT_CTX, VCL_TIME t, VCL_REAL r)
181
{
182 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
183
184 2
        if (!isfinite(t))
185 0
                return (r);
186
187 2
        return (t);
188
}
189
190
VCL_TIME v_matchproto_(td_std_time)
191 64
vmod_time(VRT_CTX, VCL_STRING p, VCL_TIME d)
192
{
193
        double r;
194
195 64
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
196
197 64
        r = VTIM_parse(p);
198 64
        if (r)
199 20
                return (r);
200 44
        return (vmod_real(ctx, p, d));
201
}