lsquic_version.c revision 92f6e17b
1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 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_039] = { 'Q', '0', '3', '9', },
12c95974e9SDmitri Tikhonov    [LSQVER_043] = { 'Q', '0', '4', '3', },
13c7d81ce1SDmitri Tikhonov    [LSQVER_046] = { 'Q', '0', '4', '6', },
149626cfc2SDmitri Tikhonov#if LSQUIC_USE_Q098
159626cfc2SDmitri Tikhonov    [LSQVER_098] = { 'Q', '0', '9', '8', },
169626cfc2SDmitri Tikhonov#endif
1792f6e17bSDmitri Tikhonov    [LSQVER_ID23] = { 0xFF, 0, 0, 23, },
185392f7a3SLiteSpeed Tech    [LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, },
1950aadb33SDmitri Tikhonov};
2050aadb33SDmitri Tikhonov
2150aadb33SDmitri Tikhonov
2250aadb33SDmitri Tikhonovuint32_t
2350aadb33SDmitri Tikhonovlsquic_ver2tag (unsigned version)
2450aadb33SDmitri Tikhonov{
2550aadb33SDmitri Tikhonov    lsquic_ver_tag_t tag;
2650aadb33SDmitri Tikhonov    if (version < N_LSQVER)
2750aadb33SDmitri Tikhonov    {
2850aadb33SDmitri Tikhonov        memcpy(&tag, version_tags[version], 4);
2950aadb33SDmitri Tikhonov        return tag;
3050aadb33SDmitri Tikhonov    }
3150aadb33SDmitri Tikhonov    else
3250aadb33SDmitri Tikhonov        return 0;
3350aadb33SDmitri Tikhonov}
3450aadb33SDmitri Tikhonov
3550aadb33SDmitri Tikhonov
3650aadb33SDmitri Tikhonovenum lsquic_version
3750aadb33SDmitri Tikhonovlsquic_tag2ver (uint32_t ver_tag)
3850aadb33SDmitri Tikhonov{
3950aadb33SDmitri Tikhonov    unsigned n;
4050aadb33SDmitri Tikhonov    for (n = 0; n < sizeof(version_tags) / sizeof(version_tags[0]); ++n)
4150aadb33SDmitri Tikhonov        if (0 == memcmp(version_tags[n], &ver_tag, sizeof(ver_tag)))
4250aadb33SDmitri Tikhonov            return n;
4350aadb33SDmitri Tikhonov    return -1;
4450aadb33SDmitri Tikhonov}
4550aadb33SDmitri Tikhonov
4650aadb33SDmitri Tikhonov
475392f7a3SLiteSpeed Techconst char *const lsquic_ver2str[N_LSQVER] = {
485392f7a3SLiteSpeed Tech    [LSQVER_039] = "Q039",
495392f7a3SLiteSpeed Tech    [LSQVER_043] = "Q043",
505392f7a3SLiteSpeed Tech    [LSQVER_046] = "Q046",
515392f7a3SLiteSpeed Tech#if LSQUIC_USE_Q098
525392f7a3SLiteSpeed Tech    [LSQVER_098] = "Q098",
535392f7a3SLiteSpeed Tech#endif
5492f6e17bSDmitri Tikhonov    [LSQVER_ID23] = "FF000017",
555392f7a3SLiteSpeed Tech    [LSQVER_VERNEG] = "FAFAFAFA",
565392f7a3SLiteSpeed Tech};
575392f7a3SLiteSpeed Tech
585392f7a3SLiteSpeed Tech
5950aadb33SDmitri Tikhonovenum lsquic_version
6050aadb33SDmitri Tikhonovlsquic_str2ver (const char *str, size_t len)
6150aadb33SDmitri Tikhonov{
625392f7a3SLiteSpeed Tech    enum lsquic_version ver;
6350aadb33SDmitri Tikhonov    uint32_t tag;
6450aadb33SDmitri Tikhonov
6550aadb33SDmitri Tikhonov    if (len == sizeof(tag) && 'Q' == str[0])
6650aadb33SDmitri Tikhonov    {
6750aadb33SDmitri Tikhonov        memcpy(&tag, str, sizeof(tag));
6850aadb33SDmitri Tikhonov        return lsquic_tag2ver(tag);
6950aadb33SDmitri Tikhonov    }
7050aadb33SDmitri Tikhonov
715392f7a3SLiteSpeed Tech    for (ver = 0; ver < N_LSQVER; ++ver)
725392f7a3SLiteSpeed Tech        if (strlen(lsquic_ver2str[ver]) == len
735392f7a3SLiteSpeed Tech            && strncasecmp(lsquic_ver2str[ver], str, len) == 0)
745392f7a3SLiteSpeed Tech        {
755392f7a3SLiteSpeed Tech            return ver;
765392f7a3SLiteSpeed Tech        }
7750aadb33SDmitri Tikhonov
785392f7a3SLiteSpeed Tech    return -1;
795392f7a3SLiteSpeed Tech}
8050aadb33SDmitri Tikhonov
8150aadb33SDmitri Tikhonov
825392f7a3SLiteSpeed Techint
835392f7a3SLiteSpeed Techlsquic_gen_ver_tags (unsigned char *buf, size_t bufsz, unsigned version_bitmask)
845392f7a3SLiteSpeed Tech{
855392f7a3SLiteSpeed Tech    unsigned n;
865392f7a3SLiteSpeed Tech    lsquic_ver_tag_t tag;
875392f7a3SLiteSpeed Tech    unsigned char *p = buf;
885392f7a3SLiteSpeed Tech    unsigned char *const pend = p + bufsz;
895392f7a3SLiteSpeed Tech    for (n = 0; version_bitmask; ++n)
905392f7a3SLiteSpeed Tech    {
915392f7a3SLiteSpeed Tech        if (version_bitmask & (1 << n))
925392f7a3SLiteSpeed Tech        {
935392f7a3SLiteSpeed Tech            if (p + 4 > pend)
945392f7a3SLiteSpeed Tech                return -1;
955392f7a3SLiteSpeed Tech            version_bitmask &= ~(1 << n);
965392f7a3SLiteSpeed Tech            tag = lsquic_ver2tag(n);
975392f7a3SLiteSpeed Tech            if (0 == tag)
985392f7a3SLiteSpeed Tech                return -1;
995392f7a3SLiteSpeed Tech            memcpy(p, &tag, 4);
1005392f7a3SLiteSpeed Tech            p += 4;
1015392f7a3SLiteSpeed Tech        }
1025392f7a3SLiteSpeed Tech    }
1035392f7a3SLiteSpeed Tech    return p - buf;
1045392f7a3SLiteSpeed Tech}
105