11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * ngtcp2 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Copyright (c) 2017 ngtcp2 contributors 51cb0ef41Sopenharmony_ci * 61cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 71cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the 81cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 91cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 101cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 111cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 121cb0ef41Sopenharmony_ci * the following conditions: 131cb0ef41Sopenharmony_ci * 141cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be 151cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software. 161cb0ef41Sopenharmony_ci * 171cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 181cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 191cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 201cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 211cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 221cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 231cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 241cb0ef41Sopenharmony_ci */ 251cb0ef41Sopenharmony_ci#ifndef NGTCP2_ROB_H 261cb0ef41Sopenharmony_ci#define NGTCP2_ROB_H 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci#ifdef HAVE_CONFIG_H 291cb0ef41Sopenharmony_ci# include <config.h> 301cb0ef41Sopenharmony_ci#endif /* HAVE_CONFIG_H */ 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include <ngtcp2/ngtcp2.h> 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci#include "ngtcp2_mem.h" 351cb0ef41Sopenharmony_ci#include "ngtcp2_range.h" 361cb0ef41Sopenharmony_ci#include "ngtcp2_ksl.h" 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci/* 391cb0ef41Sopenharmony_ci * ngtcp2_rob_gap represents the gap, which is the range of stream 401cb0ef41Sopenharmony_ci * data that is not received yet. 411cb0ef41Sopenharmony_ci */ 421cb0ef41Sopenharmony_citypedef struct ngtcp2_rob_gap { 431cb0ef41Sopenharmony_ci /* range is the range of this gap. */ 441cb0ef41Sopenharmony_ci ngtcp2_range range; 451cb0ef41Sopenharmony_ci} ngtcp2_rob_gap; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci/* 481cb0ef41Sopenharmony_ci * ngtcp2_rob_gap_new allocates new ngtcp2_rob_gap object, and assigns 491cb0ef41Sopenharmony_ci * its pointer to |*pg|. The caller should call ngtcp2_rob_gap_del to 501cb0ef41Sopenharmony_ci * delete it when it is no longer used. The range of the gap is 511cb0ef41Sopenharmony_ci * [begin, end). |mem| is custom memory allocator to allocate memory. 521cb0ef41Sopenharmony_ci * 531cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 541cb0ef41Sopenharmony_ci * negative error codes: 551cb0ef41Sopenharmony_ci * 561cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 571cb0ef41Sopenharmony_ci * Out of memory. 581cb0ef41Sopenharmony_ci */ 591cb0ef41Sopenharmony_ciint ngtcp2_rob_gap_new(ngtcp2_rob_gap **pg, uint64_t begin, uint64_t end, 601cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci/* 631cb0ef41Sopenharmony_ci * ngtcp2_rob_gap_del deallocates |g|. It deallocates the memory 641cb0ef41Sopenharmony_ci * pointed by |g| it self. |mem| is custom memory allocator to 651cb0ef41Sopenharmony_ci * deallocate memory. 661cb0ef41Sopenharmony_ci */ 671cb0ef41Sopenharmony_civoid ngtcp2_rob_gap_del(ngtcp2_rob_gap *g, const ngtcp2_mem *mem); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci/* 701cb0ef41Sopenharmony_ci * ngtcp2_rob_data holds the buffered stream data. 711cb0ef41Sopenharmony_ci */ 721cb0ef41Sopenharmony_citypedef struct ngtcp2_rob_data { 731cb0ef41Sopenharmony_ci /* range is the range of this gap. */ 741cb0ef41Sopenharmony_ci ngtcp2_range range; 751cb0ef41Sopenharmony_ci /* begin points to the buffer. */ 761cb0ef41Sopenharmony_ci uint8_t *begin; 771cb0ef41Sopenharmony_ci /* end points to the one beyond of the last byte of the buffer */ 781cb0ef41Sopenharmony_ci uint8_t *end; 791cb0ef41Sopenharmony_ci} ngtcp2_rob_data; 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci/* 821cb0ef41Sopenharmony_ci * ngtcp2_rob_data_new allocates new ngtcp2_rob_data object, and 831cb0ef41Sopenharmony_ci * assigns its pointer to |*pd|. The caller should call 841cb0ef41Sopenharmony_ci * ngtcp2_rob_data_del to delete it when it is no longer used. 851cb0ef41Sopenharmony_ci * |offset| is the stream offset of the first byte of this data. 861cb0ef41Sopenharmony_ci * |chunk| is the size of the buffer. |offset| must be multiple of 871cb0ef41Sopenharmony_ci * |chunk|. |mem| is custom memory allocator to allocate memory. 881cb0ef41Sopenharmony_ci * 891cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 901cb0ef41Sopenharmony_ci * negative error codes: 911cb0ef41Sopenharmony_ci * 921cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 931cb0ef41Sopenharmony_ci * Out of memory. 941cb0ef41Sopenharmony_ci */ 951cb0ef41Sopenharmony_ciint ngtcp2_rob_data_new(ngtcp2_rob_data **pd, uint64_t offset, size_t chunk, 961cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci/* 991cb0ef41Sopenharmony_ci * ngtcp2_rob_data_del deallocates |d|. It deallocates the memory 1001cb0ef41Sopenharmony_ci * pointed by |d| itself. |mem| is custom memory allocator to 1011cb0ef41Sopenharmony_ci * deallocate memory. 1021cb0ef41Sopenharmony_ci */ 1031cb0ef41Sopenharmony_civoid ngtcp2_rob_data_del(ngtcp2_rob_data *d, const ngtcp2_mem *mem); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci/* 1061cb0ef41Sopenharmony_ci * ngtcp2_rob is the reorder buffer which reassembles stream data 1071cb0ef41Sopenharmony_ci * received in out of order. 1081cb0ef41Sopenharmony_ci */ 1091cb0ef41Sopenharmony_citypedef struct ngtcp2_rob { 1101cb0ef41Sopenharmony_ci /* gapksl maintains the range of offset which is not received 1111cb0ef41Sopenharmony_ci yet. Initially, its range is [0, UINT64_MAX). */ 1121cb0ef41Sopenharmony_ci ngtcp2_ksl gapksl; 1131cb0ef41Sopenharmony_ci /* dataksl maintains the list of buffers which store received data 1141cb0ef41Sopenharmony_ci ordered by stream offset. */ 1151cb0ef41Sopenharmony_ci ngtcp2_ksl dataksl; 1161cb0ef41Sopenharmony_ci /* mem is custom memory allocator */ 1171cb0ef41Sopenharmony_ci const ngtcp2_mem *mem; 1181cb0ef41Sopenharmony_ci /* chunk is the size of each buffer in data field */ 1191cb0ef41Sopenharmony_ci size_t chunk; 1201cb0ef41Sopenharmony_ci} ngtcp2_rob; 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci/* 1231cb0ef41Sopenharmony_ci * ngtcp2_rob_init initializes |rob|. |chunk| is the size of buffer 1241cb0ef41Sopenharmony_ci * per chunk. 1251cb0ef41Sopenharmony_ci * 1261cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 1271cb0ef41Sopenharmony_ci * negative error codes: 1281cb0ef41Sopenharmony_ci * 1291cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 1301cb0ef41Sopenharmony_ci * Out of memory. 1311cb0ef41Sopenharmony_ci */ 1321cb0ef41Sopenharmony_ciint ngtcp2_rob_init(ngtcp2_rob *rob, size_t chunk, const ngtcp2_mem *mem); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci/* 1351cb0ef41Sopenharmony_ci * ngtcp2_rob_free frees resources allocated for |rob|. 1361cb0ef41Sopenharmony_ci */ 1371cb0ef41Sopenharmony_civoid ngtcp2_rob_free(ngtcp2_rob *rob); 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci/* 1401cb0ef41Sopenharmony_ci * ngtcp2_rob_push adds new data of length |datalen| at the stream 1411cb0ef41Sopenharmony_ci * offset |offset|. 1421cb0ef41Sopenharmony_ci * 1431cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 1441cb0ef41Sopenharmony_ci * negative error codes: 1451cb0ef41Sopenharmony_ci * 1461cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 1471cb0ef41Sopenharmony_ci * Out of memory 1481cb0ef41Sopenharmony_ci */ 1491cb0ef41Sopenharmony_ciint ngtcp2_rob_push(ngtcp2_rob *rob, uint64_t offset, const uint8_t *data, 1501cb0ef41Sopenharmony_ci size_t datalen); 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci/* 1531cb0ef41Sopenharmony_ci * ngtcp2_rob_remove_prefix removes gap up to |offset|, exclusive. It 1541cb0ef41Sopenharmony_ci * also removes data buffer if it is completely included in |offset|. 1551cb0ef41Sopenharmony_ci * 1561cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 1571cb0ef41Sopenharmony_ci * negative error codes: 1581cb0ef41Sopenharmony_ci * 1591cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 1601cb0ef41Sopenharmony_ci * Out of memory 1611cb0ef41Sopenharmony_ci */ 1621cb0ef41Sopenharmony_ciint ngtcp2_rob_remove_prefix(ngtcp2_rob *rob, uint64_t offset); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci/* 1651cb0ef41Sopenharmony_ci * ngtcp2_rob_data_at stores the pointer to the buffer of stream 1661cb0ef41Sopenharmony_ci * offset |offset| to |*pdest| if it is available, and returns the 1671cb0ef41Sopenharmony_ci * valid length of available data. If no data is available, it 1681cb0ef41Sopenharmony_ci * returns 0. 1691cb0ef41Sopenharmony_ci */ 1701cb0ef41Sopenharmony_cisize_t ngtcp2_rob_data_at(ngtcp2_rob *rob, const uint8_t **pdest, 1711cb0ef41Sopenharmony_ci uint64_t offset); 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci/* 1741cb0ef41Sopenharmony_ci * ngtcp2_rob_pop clears data at stream offset |offset| of length 1751cb0ef41Sopenharmony_ci * |len|. 1761cb0ef41Sopenharmony_ci * 1771cb0ef41Sopenharmony_ci * |offset| must be the offset given in ngtcp2_rob_data_at. |len| 1781cb0ef41Sopenharmony_ci * must be the return value of ngtcp2_rob_data_at when |offset| is 1791cb0ef41Sopenharmony_ci * passed. 1801cb0ef41Sopenharmony_ci * 1811cb0ef41Sopenharmony_ci * Caller should call this function from offset 0 in non-decreasing 1821cb0ef41Sopenharmony_ci * order. 1831cb0ef41Sopenharmony_ci */ 1841cb0ef41Sopenharmony_civoid ngtcp2_rob_pop(ngtcp2_rob *rob, uint64_t offset, size_t len); 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci/* 1871cb0ef41Sopenharmony_ci * ngtcp2_rob_first_gap_offset returns the offset to the first gap. 1881cb0ef41Sopenharmony_ci * If there is no gap, it returns UINT64_MAX. 1891cb0ef41Sopenharmony_ci */ 1901cb0ef41Sopenharmony_ciuint64_t ngtcp2_rob_first_gap_offset(ngtcp2_rob *rob); 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci/* 1931cb0ef41Sopenharmony_ci * ngtcp2_rob_data_buffered returns nonzero if any data is buffered. 1941cb0ef41Sopenharmony_ci */ 1951cb0ef41Sopenharmony_ciint ngtcp2_rob_data_buffered(ngtcp2_rob *rob); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci#endif /* NGTCP2_ROB_H */ 198