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