varnish-cache/bin/varnishtest/vtc_h2_hpack.c
0
/*-
1
 * Copyright (c) 2008-2016 Varnish Software AS
2
 * All rights reserved.
3
 *
4
 * Author: Guillaume Quintard <guillaume.quintard@gmail.com>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include <stdint.h>
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <string.h>
34
35
36
#include "vdef.h"
37
38
#include "vas.h"
39
#include "vqueue.h"
40
41
#include "hpack.h"
42
#include "vtc_h2_priv.h"
43
44
struct symbol {
45
        uint32_t        val;
46
        uint8_t         size;
47
};
48
49
static const struct symbol coding_table[] = {
50
#define HPACK(i, v, l) {v, l},
51
#include "vtc_h2_enctbl.h"
52
#undef HPACK
53
        {0, 0}
54
};
55
56
#include "vtc_h2_dectbl.h"
57
58
#define MASK(pack, n) (pack >> (64 - n))
59
static int
60 440
huff_decode(char *str, int nm, struct hpk_iter *iter, int ilen)
61
{
62 440
        int l = 0;
63 440
        uint64_t pack = 0;
64 440
        unsigned pl = 0; /* pack length*/
65 440
        struct stbl *tbl = &tbl_0;
66
        struct ssym *sym;
67
68 440
        (void)nm;
69 5080
        while (ilen > 0 || pl != 0) {
70
                /* make sure we have enough data*/
71 5080
                if (pl < tbl->msk) {
72 1080
                        if (ilen == 0) {
73 440
                                if (pl == 0 || (MASK(pack, pl) ==
74 440
                                                (unsigned)((1U << pl) - 1U))) {
75 440
                                        assert(tbl == &tbl_0);
76 440
                                        return (l);
77
                                }
78 0
                        }
79
                        /* fit as many bytes as we can in pack */
80 4280
                        while (pl <= 56 && ilen > 0) {
81 7280
                                pack |= (uint64_t)(*iter->buf & 0xff)
82 3640
                                        << (56 - pl);
83 3640
                                pl += 8;
84 3640
                                iter->buf++;
85 3640
                                ilen--;
86
                        }
87 640
                }
88 4640
                assert(tbl);
89 4640
                assert(tbl->msk);
90 4640
                sym = &tbl->syms[MASK(pack, tbl->msk)];
91
92 4640
                assert(sym->csm <= tbl->msk);
93
94 4640
                if (sym->csm == 0 || pl < sym->csm)
95 0
                        return (0);
96
97 4640
                assert(sym->csm <= 8);
98 4640
                pack <<= sym->csm;
99 4640
                assert(sym->csm <= pl);
100 4640
                pl -= sym->csm;
101 4640
                if (sym->nxt) {
102 0
                        tbl = sym->nxt;
103 0
                        continue;
104
                }
105 4640
                str[l++] = sym->chr;
106 4640
                tbl = &tbl_0;
107
        }
108 0
        return (l);
109 440
}
110
111
/* inspired from Dridi Boukelmoune's cashpack. */
112
static enum hpk_result
113 560
huff_encode(struct hpk_iter *iter, const char *str, int len)
114
{
115 560
        uint64_t pack = 0;
116 560
        int pl = 0; /* pack length*/
117
        uint32_t        v;
118
        uint8_t         s;
119
120 560
        assert(iter->buf < iter->end);
121
122 6320
        while (len--) {
123 5760
                v = coding_table[(uint8_t)*str].val;
124 5760
                s = coding_table[(uint8_t)*str].size;
125
126 5760
                pl += s;
127 5760
                pack |= (uint64_t)v << (64 - pl);
128
129 9760
                while (pl >= 8) {
130 4000
                        if (iter->buf == iter->end)
131 0
                                return (hpk_done);
132 4000
                        *iter->buf = (char)(pack >> 56);
133 4000
                        iter->buf++;
134 4000
                        pack <<= 8;
135 4000
                        pl -= 8;
136
                }
137 5760
                str++;
138
        }
139
140
        /* padding */
141 560
        if (pl) {
142 560
                assert(pl < 8);
143 560
                if (iter->buf == iter->end)
144 0
                        return (hpk_done);
145 560
                pl += 8;
146 560
                pack |= (uint64_t)0xff << (64 - pl);
147 560
                *iter->buf = (char)(pack >> 56);
148 560
                iter->buf++;
149 560
        }
150
151 560
        return (hpk_more);
152 560
}
153
154
static int
155 146400
huff_simulate(const char *str, int ilen, int huff)
156
{
157 146400
        int olen = 0;
158 146400
        if (!huff || !ilen)
159 145840
                return (ilen);
160 6320
        while (ilen--) {
161 5760
                olen += coding_table[(unsigned char)*str].size;
162 5760
                str++;
163
        }
164 560
        return ((olen + 7) / 8);
165 146400
}
166
167
static enum hpk_result
168 79920
num_decode(uint32_t *result, struct hpk_iter *iter, uint8_t prefix)
169
{
170 79920
        uint8_t shift = 0;
171
172 79920
        assert(iter->buf < iter->end);
173 79920
        assert(prefix);
174 79920
        assert(prefix <= 8);
175
176 79920
        *result = 0;
177 79920
        *result = *iter->buf & (0xff >> (8-prefix));
178 79920
        if (*result < (1U << prefix) - 1U) {
179 61560
                iter->buf++;
180 61560
                return (ITER_DONE(iter));
181
        }
182 18360
        do {
183 18520
                iter->buf++;
184 18520
                if (iter->end == iter->buf)
185 0
                        return (hpk_err);
186
                /* check for overflow */
187 18520
                if ((UINT32_MAX - *result) >> shift < (*iter->buf & 0x7f))
188 0
                        return (hpk_err);
189
190 18520
                *result += (uint32_t)(*iter->buf & 0x7f) << shift;
191 18520
                shift += 7;
192 18520
        } while (*iter->buf & 0x80);
193 18360
        iter->buf++;
194
195 18360
        return (ITER_DONE(iter));
196 79920
}
197
198
static enum hpk_result
199 148720
num_encode(struct hpk_iter *iter, uint8_t prefix, uint32_t num)
200
{
201 148720
        assert(prefix);
202 148720
        assert(prefix <= 8);
203 148720
        assert(iter->buf < iter->end);
204
205 148720
        uint8_t pmax = (1U << prefix) - 1U;
206
207 148720
        *iter->buf &= 0xffU << prefix;
208 148720
        if (num <= pmax) {
209 108680
                *iter->buf++ |= num;
210 108680
                return (ITER_DONE(iter));
211 40040
        } else if (iter->end - iter->buf < 2)
212 0
                return (hpk_err);
213
214 40040
        iter->buf[0] |= pmax;
215 40040
        num -= pmax;
216 40040
        do {
217 80040
                iter->buf++;
218 80040
                if (iter->end == iter->buf)
219 0
                        return (hpk_err);
220 80040
                *iter->buf = num % 128;
221 80040
                *iter->buf |= 0x80;
222 80040
                num /= 128;
223 80040
        } while (num);
224 40040
        *iter->buf++ &= 127;
225 40040
        return (ITER_DONE(iter));
226 148720
}
227
228
static enum hpk_result
229 146400
str_encode(struct hpk_iter *iter, const struct hpk_txt *t)
230
{
231 146400
        int slen = huff_simulate(t->ptr, t->len, t->huff);
232 146400
        assert(iter->buf < iter->end);
233 146400
        if (t->huff)
234 560
                *iter->buf = 0x80;
235
        else
236 145840
                *iter->buf = 0;
237
238 146400
        if (hpk_err == num_encode(iter, 7, slen))
239 0
                return (hpk_err);
240
241 146400
        if (slen > iter->end - iter->buf)
242 0
                return (hpk_err);
243
244 146400
        if (t->huff) {
245 560
                return (huff_encode(iter, t->ptr, t->len));
246
        } else {
247 145840
                memcpy(iter->buf, t->ptr, slen);
248 145840
                iter->buf += slen;
249 145840
                return (ITER_DONE(iter));
250
        }
251 146400
}
252
253
static enum hpk_result
254 43840
str_decode(struct hpk_iter *iter, struct hpk_txt *t)
255
{
256
        uint32_t num;
257
        int huff;
258
259 43840
        assert(iter->buf < iter->end);
260
261 43840
        huff = (*iter->buf & 0x80);
262 43840
        if (hpk_more != num_decode(&num, iter, 7))
263 0
                return (hpk_err);
264 43840
        assert(iter->buf < iter->end);
265 43840
        if (num > (unsigned)(iter->end - iter->buf))
266 0
                return (hpk_err);
267 43840
        if (huff) { /*Huffman encoding */
268 440
                t->ptr = malloc((num * 8L) / 5L + 1L);
269 440
                AN(t->ptr);
270 440
                num = huff_decode(t->ptr, (num * 8) / 5, iter, num);
271 440
                if (!num) {
272 0
                        free(t->ptr);
273 0
                        return (hpk_err);
274
                }
275 440
                t->huff = 1;
276
                /* XXX: do we care? */
277 440
                t->ptr = realloc(t->ptr, num + 1L);
278 440
                AN(t->ptr);
279 440
        } else { /* literal string */
280 43400
                t->huff = 0;
281 43400
                t->ptr = malloc(num + 1L);
282 43400
                AN(t->ptr);
283 43400
                memcpy(t->ptr, iter->buf, num);
284 43400
                iter->buf += num;
285
        }
286
287 43840
        t->ptr[num] = '\0';
288 43840
        t->len = num;
289
290 43840
        return (ITER_DONE(iter));
291 43840
}
292
293
static inline void
294 28160
txtcpy(struct hpk_txt *to, const struct hpk_txt *from)
295
{
296
        //AZ(to->ptr);
297 28160
        to->ptr = malloc(from->len + 1L);
298 28160
        AN(to->ptr);
299 28160
        memcpy(to->ptr, from->ptr, from->len + 1L);
300 28160
        to->len = from->len;
301 28160
}
302
303
int
304 50760
gethpk_iterLen(const struct hpk_iter *iter)
305
{
306 50760
        return (iter->buf - iter->orig);
307
}
308
309
enum hpk_result
310 36080
HPK_DecHdr(struct hpk_iter *iter, struct hpk_hdr *header)
311
{
312 36080
        int pref = 0;
313
        const struct hpk_txt *t;
314
        uint32_t num;
315 36080
        int must_index = 0;
316 36080
        assert(iter);
317 36080
        assert(iter->buf < iter->end);
318
        /* Indexed Header Field */
319 36080
        if (*iter->buf & 128) {
320 4600
                header->t = hpk_idx;
321 4600
                if (hpk_err == num_decode(&num, iter, 7))
322 0
                        return (hpk_err);
323
324 4600
                if (num) { /* indexed key and value*/
325 4600
                        t = tbl_get_key(iter->ctx, num);
326 4600
                        if (!t)
327 80
                                return (hpk_err);
328 4520
                        txtcpy(&header->key, t);
329
330 4520
                        t = tbl_get_value(iter->ctx, num);
331 4520
                        if (!t) {
332 0
                                free(header->key.ptr);
333 0
                                return (hpk_err);
334
                        }
335
336 4520
                        txtcpy(&header->value, t);
337
338 4520
                        if (iter->buf < iter->end)
339 4440
                                return (hpk_more);
340
                        else
341 80
                                return (hpk_done);
342
                } else
343 0
                        return (hpk_err);
344
345
        }
346
        /* Literal Header Field with Incremental Indexing */
347 31480
        else if (*iter->buf >> 6 == 1) {
348 720
                header->t = hpk_inc;
349 720
                pref = 6;
350 720
                must_index = 1;
351 720
        }
352
        /* Literal Header Field without Indexing */
353 30760
        else if (*iter->buf >> 4 == 0) {
354 8240
                header->t = hpk_not;
355 8240
                pref = 4;
356 8240
        }
357
        /* Literal Header Field never Indexed */
358 22520
        else if (*iter->buf >> 4 == 1) {
359 22520
                header->t = hpk_never;
360 22520
                pref = 4;
361 22520
        }
362
        /* Dynamic Table Size Update */
363
        /* XXX if under max allowed value */
364 0
        else if (*iter->buf >> 5 == 1) {
365 0
                if (hpk_done != num_decode(&num, iter, 5))
366 0
                        return (hpk_err);
367 0
                return (HPK_ResizeTbl(iter->ctx, num));
368
        } else {
369 0
                return (hpk_err);
370
        }
371
372 31480
        assert(pref);
373 31480
        if (hpk_more != num_decode(&num, iter, pref))
374 0
                return (hpk_err);
375
376 31480
        header->i = num;
377 31480
        if (num) { /* indexed key */
378 19120
                t = tbl_get_key(iter->ctx, num);
379 19120
                if (!t)
380 0
                        return (hpk_err);
381 19120
                txtcpy(&header->key, t);
382 19120
        } else {
383 12360
                if (hpk_more != str_decode(iter, &header->key)) {
384 0
                        free(header->key.ptr);
385 0
                        return (hpk_err);
386
                }
387
        }
388
389 31480
        if (hpk_err == str_decode(iter, &header->value)) {
390 0
                free(header->key.ptr);
391 0
                return (hpk_err);
392
        }
393
394 31480
        if (must_index)
395 720
                push_header(iter->ctx, header);
396 31480
        return (ITER_DONE(iter));
397 36080
}
398
399
enum hpk_result
400 75200
HPK_EncHdr(struct hpk_iter *iter, const struct hpk_hdr *h)
401
{
402
        int pref;
403 75200
        int must_index = 0;
404
        enum hpk_result ret;
405 75200
        switch (h->t) {
406
                case hpk_idx:
407 1680
                        *iter->buf = 0x80;
408 1680
                        assert(num_encode(iter, 7, h->i) != hpk_err);
409 1680
                        return (ITER_DONE(iter));
410
                case hpk_inc:
411 880
                        *iter->buf = 0x40;
412 880
                        pref = 6;
413 880
                        must_index = 1;
414 880
                        break;
415
                case hpk_not:
416 72600
                        *iter->buf = 0x00;
417 72600
                        pref = 4;
418 72600
                        break;
419
                case hpk_never:
420 40
                        *iter->buf = 0x10;
421 40
                        pref = 4;
422 40
                        break;
423
                default:
424 0
                        INCOMPL();
425 0
        }
426 73520
        if (h->i) {
427 640
                if (hpk_more != num_encode(iter, pref, h->i))
428 0
                        return (hpk_err);
429 640
        } else {
430 72880
                iter->buf++;
431 72880
                if (hpk_more != str_encode(iter, &h->key))
432 0
                        return (hpk_err);
433
        }
434 73520
        ret = str_encode(iter, &h->value);
435 73520
        if (ret == hpk_err)
436 0
                return (hpk_err);
437 73520
        if (must_index)
438 880
                push_header(iter->ctx, h);
439 73520
        return (ret);
440
441 75200
}