lsquic_version.c revision a74702c6
1/* Copyright (c) 2017 - 2022 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 [LSQVER_ID27] = { 0xFF, 0, 0, 27, }, 19 [LSQVER_ID29] = { 0xFF, 0, 0, 29, }, 20 [LSQVER_I001] = { 0, 0, 0, 1, }, 21 [LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, }, 22}; 23 24 25uint32_t 26lsquic_ver2tag (unsigned version) 27{ 28 lsquic_ver_tag_t tag; 29 if (version < N_LSQVER) 30 { 31 memcpy(&tag, version_tags[version], 4); 32 return tag; 33 } 34 else 35 return 0; 36} 37 38 39enum lsquic_version 40lsquic_tag2ver (uint32_t ver_tag) 41{ 42 unsigned n; 43 for (n = 0; n < sizeof(version_tags) / sizeof(version_tags[0]); ++n) 44 if (0 == memcmp(version_tags[n], &ver_tag, sizeof(ver_tag))) 45 return n; 46 return -1; 47} 48 49 50const char *const lsquic_ver2str[N_LSQVER] = { 51 [LSQVER_043] = "Q043", 52 [LSQVER_046] = "Q046", 53 [LSQVER_050] = "Q050", 54 [LSQVER_ID27] = "FF00001B", 55 [LSQVER_ID29] = "FF00001D", 56 [LSQVER_I001] = "00000001", 57 [LSQVER_VERNEG] = "FAFAFAFA", 58}; 59 60 61const char *const lsquic_ver2altstr[N_LSQVER] = { 62 [LSQVER_043] = NULL, 63 [LSQVER_046] = NULL, 64 [LSQVER_050] = NULL, 65 [LSQVER_ID27] = "h3-27", 66 [LSQVER_ID29] = "h3-29", 67 [LSQVER_I001] = "h3", 68 [LSQVER_VERNEG] = "VERNEG", 69}; 70 71 72enum lsquic_version 73lsquic_str2ver (const char *str, size_t len) 74{ 75 enum lsquic_version ver; 76 uint32_t tag; 77 78 if (len == sizeof(tag) && 'Q' == str[0]) 79 { 80 memcpy(&tag, str, sizeof(tag)); 81 return lsquic_tag2ver(tag); 82 } 83 84 for (ver = 0; ver < N_LSQVER; ++ver) 85 { 86 if (strlen(lsquic_ver2str[ver]) == len 87 && strncasecmp(lsquic_ver2str[ver], str, len) == 0) 88 { 89 return ver; 90 } 91 if (lsquic_ver2altstr[ver] && strlen(lsquic_ver2altstr[ver]) == len 92 && strncasecmp(lsquic_ver2altstr[ver], str, len) == 0) 93 { 94 return ver; 95 } 96 } 97 return -1; 98} 99 100 101int 102lsquic_gen_ver_tags (unsigned char *buf, size_t bufsz, unsigned version_bitmask) 103{ 104 unsigned n; 105 lsquic_ver_tag_t tag; 106 unsigned char *p = buf; 107 unsigned char *const pend = p + bufsz; 108 for (n = 0; version_bitmask; ++n) 109 { 110 if (version_bitmask & (1 << n)) 111 { 112 if (p + 4 > pend) 113 return -1; 114 version_bitmask &= ~(1 << n); 115 tag = lsquic_ver2tag(n); 116 if (0 == tag) 117 return -1; 118 memcpy(p, &tag, 4); 119 p += 4; 120 } 121 } 122 return p - buf; 123} 124