lsquic_version.c revision 5392f7a3
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <string.h>
3
4#include "lsquic.h"
5#include "lsquic_int_types.h"
6#include "lsquic_version.h"
7
8
9static const unsigned char version_tags[N_LSQVER][4] =
10{
11    [LSQVER_039] = { 'Q', '0', '3', '9', },
12    [LSQVER_043] = { 'Q', '0', '4', '3', },
13    [LSQVER_046] = { 'Q', '0', '4', '6', },
14#if LSQUIC_USE_Q098
15    [LSQVER_098] = { 'Q', '0', '9', '8', },
16#endif
17    [LSQVER_ID22] = { 0xFF, 0, 0, 22, },
18    [LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, },
19};
20
21
22uint32_t
23lsquic_ver2tag (unsigned version)
24{
25    lsquic_ver_tag_t tag;
26    if (version < N_LSQVER)
27    {
28        memcpy(&tag, version_tags[version], 4);
29        return tag;
30    }
31    else
32        return 0;
33}
34
35
36enum lsquic_version
37lsquic_tag2ver (uint32_t ver_tag)
38{
39    unsigned n;
40    for (n = 0; n < sizeof(version_tags) / sizeof(version_tags[0]); ++n)
41        if (0 == memcmp(version_tags[n], &ver_tag, sizeof(ver_tag)))
42            return n;
43    return -1;
44}
45
46
47const char *const lsquic_ver2str[N_LSQVER] = {
48    [LSQVER_039] = "Q039",
49    [LSQVER_043] = "Q043",
50    [LSQVER_046] = "Q046",
51#if LSQUIC_USE_Q098
52    [LSQVER_098] = "Q098",
53#endif
54    [LSQVER_ID22] = "FF000016",
55    [LSQVER_VERNEG] = "FAFAFAFA",
56};
57
58
59enum lsquic_version
60lsquic_str2ver (const char *str, size_t len)
61{
62    enum lsquic_version ver;
63    uint32_t tag;
64
65    if (len == sizeof(tag) && 'Q' == str[0])
66    {
67        memcpy(&tag, str, sizeof(tag));
68        return lsquic_tag2ver(tag);
69    }
70
71    for (ver = 0; ver < N_LSQVER; ++ver)
72        if (strlen(lsquic_ver2str[ver]) == len
73            && strncasecmp(lsquic_ver2str[ver], str, len) == 0)
74        {
75            return ver;
76        }
77
78    return -1;
79}
80
81
82int
83lsquic_gen_ver_tags (unsigned char *buf, size_t bufsz, unsigned version_bitmask)
84{
85    unsigned n;
86    lsquic_ver_tag_t tag;
87    unsigned char *p = buf;
88    unsigned char *const pend = p + bufsz;
89    for (n = 0; version_bitmask; ++n)
90    {
91        if (version_bitmask & (1 << n))
92        {
93            if (p + 4 > pend)
94                return -1;
95            version_bitmask &= ~(1 << n);
96            tag = lsquic_ver2tag(n);
97            if (0 == tag)
98                return -1;
99            memcpy(p, &tag, 4);
100            p += 4;
101        }
102    }
103    return p - buf;
104}
105