lsquic_version.c revision 9626cfc2
110c492f0SDmitri Tikhonov/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <string.h>
350aadb33SDmitri Tikhonov
450aadb33SDmitri Tikhonov#include "lsquic.h"
550aadb33SDmitri Tikhonov#include "lsquic_int_types.h"
650aadb33SDmitri Tikhonov#include "lsquic_version.h"
750aadb33SDmitri Tikhonov
850aadb33SDmitri Tikhonov
950aadb33SDmitri Tikhonovstatic const unsigned char version_tags[N_LSQVER][4] =
1050aadb33SDmitri Tikhonov{
1150aadb33SDmitri Tikhonov    [LSQVER_035] = { 'Q', '0', '3', '5', },
1250aadb33SDmitri Tikhonov    [LSQVER_039] = { 'Q', '0', '3', '9', },
13c95974e9SDmitri Tikhonov    [LSQVER_043] = { 'Q', '0', '4', '3', },
149626cfc2SDmitri Tikhonov    [LSQVER_044] = { 'Q', '0', '4', '4', },
159626cfc2SDmitri Tikhonov#if LSQUIC_USE_Q098
169626cfc2SDmitri Tikhonov    [LSQVER_098] = { 'Q', '0', '9', '8', },
179626cfc2SDmitri Tikhonov#endif
1850aadb33SDmitri Tikhonov};
1950aadb33SDmitri Tikhonov
2050aadb33SDmitri Tikhonov
2150aadb33SDmitri Tikhonovuint32_t
2250aadb33SDmitri Tikhonovlsquic_ver2tag (unsigned version)
2350aadb33SDmitri Tikhonov{
2450aadb33SDmitri Tikhonov    lsquic_ver_tag_t tag;
2550aadb33SDmitri Tikhonov    if (version < N_LSQVER)
2650aadb33SDmitri Tikhonov    {
2750aadb33SDmitri Tikhonov        memcpy(&tag, version_tags[version], 4);
2850aadb33SDmitri Tikhonov        return tag;
2950aadb33SDmitri Tikhonov    }
3050aadb33SDmitri Tikhonov    else
3150aadb33SDmitri Tikhonov        return 0;
3250aadb33SDmitri Tikhonov}
3350aadb33SDmitri Tikhonov
3450aadb33SDmitri Tikhonov
3550aadb33SDmitri Tikhonovenum lsquic_version
3650aadb33SDmitri Tikhonovlsquic_tag2ver (uint32_t ver_tag)
3750aadb33SDmitri Tikhonov{
3850aadb33SDmitri Tikhonov    unsigned n;
3950aadb33SDmitri Tikhonov    for (n = 0; n < sizeof(version_tags) / sizeof(version_tags[0]); ++n)
4050aadb33SDmitri Tikhonov        if (0 == memcmp(version_tags[n], &ver_tag, sizeof(ver_tag)))
4150aadb33SDmitri Tikhonov            return n;
4250aadb33SDmitri Tikhonov    return -1;
4350aadb33SDmitri Tikhonov}
4450aadb33SDmitri Tikhonov
4550aadb33SDmitri Tikhonov
4650aadb33SDmitri Tikhonovenum lsquic_version
4750aadb33SDmitri Tikhonovlsquic_str2ver (const char *str, size_t len)
4850aadb33SDmitri Tikhonov{
4950aadb33SDmitri Tikhonov    uint32_t tag;
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonov    if (len == sizeof(tag) && 'Q' == str[0])
5250aadb33SDmitri Tikhonov    {
5350aadb33SDmitri Tikhonov        memcpy(&tag, str, sizeof(tag));
5450aadb33SDmitri Tikhonov        return lsquic_tag2ver(tag);
5550aadb33SDmitri Tikhonov    }
5650aadb33SDmitri Tikhonov    else
5750aadb33SDmitri Tikhonov        return -1;
5850aadb33SDmitri Tikhonov}
5950aadb33SDmitri Tikhonov
6050aadb33SDmitri Tikhonov
6150aadb33SDmitri Tikhonovconst char *const lsquic_ver2str[N_LSQVER] = {
6250aadb33SDmitri Tikhonov    [LSQVER_035] = "Q035",
6350aadb33SDmitri Tikhonov    [LSQVER_039] = "Q039",
64c95974e9SDmitri Tikhonov    [LSQVER_043] = "Q043",
659626cfc2SDmitri Tikhonov    [LSQVER_044] = "Q044",
669626cfc2SDmitri Tikhonov#if LSQUIC_USE_Q098
679626cfc2SDmitri Tikhonov    [LSQVER_098] = "Q098",
689626cfc2SDmitri Tikhonov#endif
6950aadb33SDmitri Tikhonov};
7050aadb33SDmitri Tikhonov
7150aadb33SDmitri Tikhonov
7250aadb33SDmitri Tikhonovint
739626cfc2SDmitri Tikhonovlsquic_gen_ver_tags (unsigned char *buf, size_t bufsz, unsigned version_bitmask)
7450aadb33SDmitri Tikhonov{
7550aadb33SDmitri Tikhonov    unsigned n;
7650aadb33SDmitri Tikhonov    lsquic_ver_tag_t tag;
7750aadb33SDmitri Tikhonov    unsigned char *p = buf;
7850aadb33SDmitri Tikhonov    unsigned char *const pend = p + bufsz;
7950aadb33SDmitri Tikhonov    for (n = 0; version_bitmask; ++n)
8050aadb33SDmitri Tikhonov    {
8150aadb33SDmitri Tikhonov        if (version_bitmask & (1 << n))
8250aadb33SDmitri Tikhonov        {
8350aadb33SDmitri Tikhonov            if (p + 4 > pend)
8450aadb33SDmitri Tikhonov                return -1;
8550aadb33SDmitri Tikhonov            version_bitmask &= ~(1 << n);
8650aadb33SDmitri Tikhonov            tag = lsquic_ver2tag(n);
8750aadb33SDmitri Tikhonov            if (0 == tag)
8850aadb33SDmitri Tikhonov                return -1;
8950aadb33SDmitri Tikhonov            memcpy(p, &tag, 4);
9050aadb33SDmitri Tikhonov            p += 4;
9150aadb33SDmitri Tikhonov        }
9250aadb33SDmitri Tikhonov    }
9350aadb33SDmitri Tikhonov    return p - buf;
9450aadb33SDmitri Tikhonov}
95