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