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