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