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