1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
25392f7a3SLiteSpeed Tech#include <stdint.h>
35392f7a3SLiteSpeed Tech#include <stdlib.h>
45392f7a3SLiteSpeed Tech
55392f7a3SLiteSpeed Tech#include "lsquic_packet_common.h"
65392f7a3SLiteSpeed Tech#include "lsquic_packet_gquic.h"
75392f7a3SLiteSpeed Tech
85392f7a3SLiteSpeed Tech
95392f7a3SLiteSpeed Tech
105392f7a3SLiteSpeed Techlsquic_packno_t
11a5fa05f9SDmitri Tikhonovlsquic_restore_packno (lsquic_packno_t cur_packno,
125392f7a3SLiteSpeed Tech                unsigned len,
135392f7a3SLiteSpeed Tech                lsquic_packno_t max_packno)
145392f7a3SLiteSpeed Tech{
155392f7a3SLiteSpeed Tech    lsquic_packno_t candidates[3], epoch_delta;
165392f7a3SLiteSpeed Tech    int64_t diffs[3];
175392f7a3SLiteSpeed Tech    unsigned min;
185392f7a3SLiteSpeed Tech
195392f7a3SLiteSpeed Tech    epoch_delta = 1ULL << (len << 3);
205392f7a3SLiteSpeed Tech    candidates[1] = (max_packno & ~(epoch_delta - 1)) + cur_packno;
215392f7a3SLiteSpeed Tech    candidates[0] = candidates[1] - epoch_delta;
225392f7a3SLiteSpeed Tech    candidates[2] = candidates[1] + epoch_delta;
235392f7a3SLiteSpeed Tech
245392f7a3SLiteSpeed Tech    diffs[0] = llabs((int64_t) candidates[0] - (int64_t) max_packno);
255392f7a3SLiteSpeed Tech    diffs[1] = llabs((int64_t) candidates[1] - (int64_t) max_packno);
265392f7a3SLiteSpeed Tech    diffs[2] = llabs((int64_t) candidates[2] - (int64_t) max_packno);
275392f7a3SLiteSpeed Tech
285392f7a3SLiteSpeed Tech    min = diffs[1] < diffs[0];
295392f7a3SLiteSpeed Tech    if (diffs[2] < diffs[min])
305392f7a3SLiteSpeed Tech        min = 2;
315392f7a3SLiteSpeed Tech
325392f7a3SLiteSpeed Tech    return candidates[min];
335392f7a3SLiteSpeed Tech}
34