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