lsquic_packet_common.c revision 10c492f0
110c492f0SDmitri Tikhonov/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_packet_common.c -- some common packet-related routines
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#include <stdio.h>
750aadb33SDmitri Tikhonov#include <stdlib.h>
850aadb33SDmitri Tikhonov
950aadb33SDmitri Tikhonov#include "lsquic_logger.h"
1050aadb33SDmitri Tikhonov#include "lsquic_packet_common.h"
1150aadb33SDmitri Tikhonov
1250aadb33SDmitri Tikhonov
1350aadb33SDmitri Tikhonovconst char *
14bfc7bfd8SDmitri Tikhonovlsquic_frame_types_to_str (char *buf, size_t bufsz,
15bfc7bfd8SDmitri Tikhonov                                           enum quic_ft_bit frame_types)
1650aadb33SDmitri Tikhonov{
1750aadb33SDmitri Tikhonov    char *p;
1850aadb33SDmitri Tikhonov    int i, w;
1950aadb33SDmitri Tikhonov    size_t sz;
2050aadb33SDmitri Tikhonov
2150aadb33SDmitri Tikhonov    if (bufsz > 0)
2250aadb33SDmitri Tikhonov        buf[0] = '\0';
2350aadb33SDmitri Tikhonov
2450aadb33SDmitri Tikhonov    p = buf;
2550aadb33SDmitri Tikhonov    for (i = 0; i < N_QUIC_FRAMES; ++i)
2650aadb33SDmitri Tikhonov    {
2750aadb33SDmitri Tikhonov        if (frame_types & (1 << i))
2850aadb33SDmitri Tikhonov        {
2950aadb33SDmitri Tikhonov            sz = bufsz - (p - buf);
3050aadb33SDmitri Tikhonov            w = snprintf(p, sz, "%.*s%s", p > buf, " ",
3150aadb33SDmitri Tikhonov                            frame_type_2_str[i] + sizeof("QUIC_FRAME_") - 1);
3250aadb33SDmitri Tikhonov            if (w > (int) sz)
3350aadb33SDmitri Tikhonov            {
3450aadb33SDmitri Tikhonov                LSQ_WARN("not enough room for all frame types");
3550aadb33SDmitri Tikhonov                break;
3650aadb33SDmitri Tikhonov            }
3750aadb33SDmitri Tikhonov            p += w;
3850aadb33SDmitri Tikhonov        }
3950aadb33SDmitri Tikhonov        frame_types &= ~(1 << i);
4050aadb33SDmitri Tikhonov    }
4150aadb33SDmitri Tikhonov
4250aadb33SDmitri Tikhonov    return buf;
4350aadb33SDmitri Tikhonov}
4450aadb33SDmitri Tikhonov
4550aadb33SDmitri Tikhonov
4650aadb33SDmitri Tikhonovenum lsquic_packno_bits
4750aadb33SDmitri Tikhonovcalc_packno_bits (lsquic_packno_t packno, lsquic_packno_t least_unacked,
4850aadb33SDmitri Tikhonov                  uint64_t n_in_flight)
4950aadb33SDmitri Tikhonov{
5050aadb33SDmitri Tikhonov    uint64_t delta;
5150aadb33SDmitri Tikhonov    unsigned bits;
5250aadb33SDmitri Tikhonov
5350aadb33SDmitri Tikhonov    delta = packno - least_unacked;
5450aadb33SDmitri Tikhonov    if (n_in_flight > delta)
5550aadb33SDmitri Tikhonov        delta = n_in_flight;
5650aadb33SDmitri Tikhonov
5750aadb33SDmitri Tikhonov    delta *= 4;
5850aadb33SDmitri Tikhonov    bits = (delta > (1ULL <<  8))
5950aadb33SDmitri Tikhonov         + (delta > (1ULL << 16))
6050aadb33SDmitri Tikhonov         + (delta > (1ULL << 32));
6150aadb33SDmitri Tikhonov
6250aadb33SDmitri Tikhonov    return bits;
6350aadb33SDmitri Tikhonov}
6450aadb33SDmitri Tikhonov
6550aadb33SDmitri Tikhonov
6650aadb33SDmitri Tikhonovlsquic_packno_t
6750aadb33SDmitri Tikhonovrestore_packno (lsquic_packno_t cur_packno,
6850aadb33SDmitri Tikhonov                enum lsquic_packno_bits cur_packno_bits,
6950aadb33SDmitri Tikhonov                lsquic_packno_t max_packno)
7050aadb33SDmitri Tikhonov{
7150aadb33SDmitri Tikhonov    lsquic_packno_t candidates[3], epoch_delta;
7250aadb33SDmitri Tikhonov    int64_t diffs[3];
7350aadb33SDmitri Tikhonov    unsigned min, len;
7450aadb33SDmitri Tikhonov
7550aadb33SDmitri Tikhonov    len = packno_bits2len(cur_packno_bits);
7650aadb33SDmitri Tikhonov    epoch_delta = 1ULL << (len << 3);
7750aadb33SDmitri Tikhonov    candidates[1] = (max_packno & ~(epoch_delta - 1)) + cur_packno;
7850aadb33SDmitri Tikhonov    candidates[0] = candidates[1] - epoch_delta;
7950aadb33SDmitri Tikhonov    candidates[2] = candidates[1] + epoch_delta;
8050aadb33SDmitri Tikhonov
8150aadb33SDmitri Tikhonov    diffs[0] = llabs((int64_t) candidates[0] - (int64_t) max_packno);
8250aadb33SDmitri Tikhonov    diffs[1] = llabs((int64_t) candidates[1] - (int64_t) max_packno);
8350aadb33SDmitri Tikhonov    diffs[2] = llabs((int64_t) candidates[2] - (int64_t) max_packno);
8450aadb33SDmitri Tikhonov
8550aadb33SDmitri Tikhonov    min = diffs[1] < diffs[0];
8650aadb33SDmitri Tikhonov    if (diffs[2] < diffs[min])
8750aadb33SDmitri Tikhonov        min = 2;
8850aadb33SDmitri Tikhonov
8950aadb33SDmitri Tikhonov    return candidates[min];
9050aadb33SDmitri Tikhonov}
91