Packages
hackney
2.0.1
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/lsquic/src/liblsquic/lsquic_version.c
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#include <string.h>
#include "lsquic.h"
#include "lsquic_int_types.h"
#include "lsquic_version.h"
#if _MSC_VER
#include "vc_compat.h"
#endif
static const unsigned char version_tags[N_LSQVER][4] =
{
[LSQVER_043] = { 'Q', '0', '4', '3', },
[LSQVER_046] = { 'Q', '0', '4', '6', },
[LSQVER_050] = { 'Q', '0', '5', '0', },
[LSQVER_ID27] = { 0xFF, 0, 0, 27, },
[LSQVER_ID29] = { 0xFF, 0, 0, 29, },
[LSQVER_I001] = { 0, 0, 0, 1, },
[LSQVER_I002] = { 0x6B, 0x33, 0x43, 0xCF },
[LSQVER_RESVED] = { 0xFA, 0xFA, 0xFA, 0xFA, },
};
uint32_t
lsquic_ver2tag (unsigned version)
{
lsquic_ver_tag_t tag;
if (version < N_LSQVER)
{
memcpy(&tag, version_tags[version], 4);
return tag;
}
else
return 0;
}
enum lsquic_version
lsquic_tag2ver (uint32_t ver_tag)
{
unsigned n;
for (n = 0; n < sizeof(version_tags) / sizeof(version_tags[0]); ++n)
if (0 == memcmp(version_tags[n], &ver_tag, sizeof(ver_tag)))
return n;
return -1;
}
enum lsquic_version
lsquic_tag2ver_fast (const unsigned char *tag)
{
unsigned char ch;
ch = *tag;
if (ch == 'Q' && *(tag + 1) == '0')
{
if (*(tag + 2) == '5' && *(tag + 3) == '0')
return LSQVER_050;
else if (*(tag + 2) == '4' && *(tag + 3) == '6')
return LSQVER_046;
}
else if (ch == 0x6b && *(tag + 1) == 0x33
&& *(tag + 2) == 0x43 && *(tag + 3) == 0xcf)
{
return LSQVER_I002;
}
else if (ch == '\0' && *(tag + 1) == 0 && *(tag + 2) == 0)
{
if (*(tag + 3) == 0x01)
return LSQVER_I001;
else if (*(tag + 3) == 0x00)
return LSQVER_VERNEG;
}
else if (ch == 0xff && *(tag + 1) == 0 && *(tag + 2) == 0)
{
if (*(tag + 3) == 0x1D)
return LSQVER_ID29;
else if (*(tag + 3) == 0x1B)
return LSQVER_ID27;
}
else if ((ch & 0xf) == 0xa && (*(tag + 1) & 0xf) == 0xa
&& (*(tag + 2) & 0xf) == 0xa && (*(tag + 3) & 0xf) == 0xa)
return LSQVER_RESVED;
return N_LSQVER;
}
const char *const lsquic_ver2str[N_LSQVER] = {
[LSQVER_043] = "Q043",
[LSQVER_046] = "Q046",
[LSQVER_050] = "Q050",
[LSQVER_ID27] = "FF00001B",
[LSQVER_ID29] = "FF00001D",
[LSQVER_I001] = "00000001",
[LSQVER_I002] = "6B3343CF",
[LSQVER_RESVED] = "FAFAFAFA",
};
const char *const lsquic_ver2altstr[N_LSQVER] = {
[LSQVER_043] = NULL,
[LSQVER_046] = NULL,
[LSQVER_050] = NULL,
[LSQVER_ID27] = "h3-27",
[LSQVER_ID29] = "h3-29",
[LSQVER_I001] = "h3",
[LSQVER_I002] = "h3-v2",
[LSQVER_RESVED] = "RESERVED",
};
enum lsquic_version
lsquic_str2ver (const char *str, size_t len)
{
enum lsquic_version ver;
uint32_t tag;
if (len == sizeof(tag) && 'Q' == str[0])
{
memcpy(&tag, str, sizeof(tag));
return lsquic_tag2ver(tag);
}
for (ver = 0; ver < N_LSQVER; ++ver)
{
if (strlen(lsquic_ver2str[ver]) == len
&& strncasecmp(lsquic_ver2str[ver], str, len) == 0)
{
return ver;
}
if (lsquic_ver2altstr[ver] && strlen(lsquic_ver2altstr[ver]) == len
&& strncasecmp(lsquic_ver2altstr[ver], str, len) == 0)
{
return ver;
}
}
return -1;
}
int
lsquic_gen_ver_tags (unsigned char *buf, size_t bufsz, unsigned version_bitmask)
{
unsigned n;
lsquic_ver_tag_t tag;
unsigned char *p = buf;
unsigned char *const pend = p + bufsz;
for (n = 0; version_bitmask; ++n)
{
if (version_bitmask & (1 << n))
{
if (p + 4 > pend)
return -1;
version_bitmask &= ~(1 << n);
tag = lsquic_ver2tag(n);
if (0 == tag)
return -1;
memcpy(p, &tag, 4);
p += 4;
}
}
return p - buf;
}