lsquic_packet_common.c revision 10c492f0
1/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_packet_common.c -- some common packet-related routines
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8
9#include "lsquic_logger.h"
10#include "lsquic_packet_common.h"
11
12
13const char *
14lsquic_frame_types_to_str (char *buf, size_t bufsz,
15                                           enum quic_ft_bit frame_types)
16{
17    char *p;
18    int i, w;
19    size_t sz;
20
21    if (bufsz > 0)
22        buf[0] = '\0';
23
24    p = buf;
25    for (i = 0; i < N_QUIC_FRAMES; ++i)
26    {
27        if (frame_types & (1 << i))
28        {
29            sz = bufsz - (p - buf);
30            w = snprintf(p, sz, "%.*s%s", p > buf, " ",
31                            frame_type_2_str[i] + sizeof("QUIC_FRAME_") - 1);
32            if (w > (int) sz)
33            {
34                LSQ_WARN("not enough room for all frame types");
35                break;
36            }
37            p += w;
38        }
39        frame_types &= ~(1 << i);
40    }
41
42    return buf;
43}
44
45
46enum lsquic_packno_bits
47calc_packno_bits (lsquic_packno_t packno, lsquic_packno_t least_unacked,
48                  uint64_t n_in_flight)
49{
50    uint64_t delta;
51    unsigned bits;
52
53    delta = packno - least_unacked;
54    if (n_in_flight > delta)
55        delta = n_in_flight;
56
57    delta *= 4;
58    bits = (delta > (1ULL <<  8))
59         + (delta > (1ULL << 16))
60         + (delta > (1ULL << 32));
61
62    return bits;
63}
64
65
66lsquic_packno_t
67restore_packno (lsquic_packno_t cur_packno,
68                enum lsquic_packno_bits cur_packno_bits,
69                lsquic_packno_t max_packno)
70{
71    lsquic_packno_t candidates[3], epoch_delta;
72    int64_t diffs[3];
73    unsigned min, len;
74
75    len = packno_bits2len(cur_packno_bits);
76    epoch_delta = 1ULL << (len << 3);
77    candidates[1] = (max_packno & ~(epoch_delta - 1)) + cur_packno;
78    candidates[0] = candidates[1] - epoch_delta;
79    candidates[2] = candidates[1] + epoch_delta;
80
81    diffs[0] = llabs((int64_t) candidates[0] - (int64_t) max_packno);
82    diffs[1] = llabs((int64_t) candidates[1] - (int64_t) max_packno);
83    diffs[2] = llabs((int64_t) candidates[2] - (int64_t) max_packno);
84
85    min = diffs[1] < diffs[0];
86    if (diffs[2] < diffs[min])
87        min = 2;
88
89    return candidates[min];
90}
91