From ac0ce07bd0f0b8b63127b0450b9e583ea1e66133 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Wed, 10 Feb 2021 08:47:05 -0500 Subject: [PATCH] Remove obsolete files --- src/liblsquic/lsquic_conn_hash.c | 245 -------- src/liblsquic/lsquic_conn_hash.h | 88 --- src/liblsquic/lsquic_parse_Q044.c | 215 ------- src/liblsquic/lsquic_parse_gquic_le.c | 851 -------------------------- 4 files changed, 1399 deletions(-) delete mode 100644 src/liblsquic/lsquic_conn_hash.c delete mode 100644 src/liblsquic/lsquic_conn_hash.h delete mode 100644 src/liblsquic/lsquic_parse_Q044.c delete mode 100644 src/liblsquic/lsquic_parse_gquic_le.c diff --git a/src/liblsquic/lsquic_conn_hash.c b/src/liblsquic/lsquic_conn_hash.c deleted file mode 100644 index 355b6f4..0000000 --- a/src/liblsquic/lsquic_conn_hash.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ -#include -#include -#include -#include - -#include "lsquic.h" -#include "lsquic_int_types.h" -#include "lsquic_conn.h" -#include "lsquic_conn_hash.h" -#include "lsquic_xxhash.h" - -#define LSQUIC_LOGGER_MODULE LSQLM_CONN_HASH -#include "lsquic_logger.h" - - -#define n_buckets(nbits) (1U << (nbits)) -#define conn_hash_mask(conn_hash) ((1 << (conn_hash)->ch_nbits) - 1) -#define conn_hash_bucket_no(conn_hash, hash) (hash & conn_hash_mask(conn_hash)) - -#if FULL_LOCAL_ADDR_SUPPORTED -#define HASHBUF_SZ (2 + sizeof(((struct sockaddr_in6 *) 0)->sin6_addr)) -#else -#define HASHBUF_SZ 2 -#endif - - -static const unsigned char * -conn2hash_by_cid (const struct lsquic_conn *lconn, unsigned char *buf, - size_t *sz) -{ - *sz = sizeof(lconn->cn_cid); - return (unsigned char *) &lconn->cn_cid; -} - - -static void -sockaddr2hash (const struct sockaddr *sa, unsigned char *buf, size_t *sz) -{ - if (sa->sa_family == AF_INET) - { - const struct sockaddr_in *const sa4 = (void *) sa; - memcpy(buf, &sa4->sin_port, 2); -#if FULL_LOCAL_ADDR_SUPPORTED - memcpy(buf + 2, &sa4->sin_addr, sizeof(sa4->sin_addr)); - *sz = 2 + sizeof(sa4->sin_addr); -#else - *sz = 2; -#endif - } - else - { - const struct sockaddr_in6 *const sa6 = (void *) sa; - memcpy(buf, &sa6->sin6_port, 2); -#if FULL_LOCAL_ADDR_SUPPORTED - memcpy(buf + 2, &sa6->sin6_addr, sizeof(sa6->sin6_addr)); - *sz = 2 + sizeof(sa6->sin6_addr); -#else - *sz = 2; -#endif - } -} - - -static const unsigned char * -conn2hash_by_addr (const struct lsquic_conn *lconn, unsigned char *buf, - size_t *sz) -{ - sockaddr2hash((struct sockaddr *) &lconn->cn_local_addr, buf, sz); - return buf; -} - - -int -conn_hash_init (struct conn_hash *conn_hash, enum conn_hash_flags flags) -{ - unsigned n; - - memset(conn_hash, 0, sizeof(*conn_hash)); - conn_hash->ch_nbits = 1; /* Start small */ - conn_hash->ch_buckets = malloc(sizeof(conn_hash->ch_buckets[0]) * - n_buckets(conn_hash->ch_nbits)); - if (!conn_hash->ch_buckets) - return -1; - for (n = 0; n < n_buckets(conn_hash->ch_nbits); ++n) - TAILQ_INIT(&conn_hash->ch_buckets[n]); - conn_hash->ch_flags = flags; - if (flags & CHF_USE_ADDR) - conn_hash->ch_conn2hash = conn2hash_by_addr; - else - conn_hash->ch_conn2hash = conn2hash_by_cid; - LSQ_INFO("initialized"); - return 0; -} - - -void -conn_hash_cleanup (struct conn_hash *conn_hash) -{ - free(conn_hash->ch_buckets); -} - - -struct lsquic_conn * -conn_hash_find_by_cid (struct conn_hash *conn_hash, lsquic_cid_t cid) -{ - const unsigned hash = XXH32(&cid, sizeof(cid), (uintptr_t) conn_hash); - const unsigned buckno = conn_hash_bucket_no(conn_hash, hash); - struct lsquic_conn *lconn; - TAILQ_FOREACH(lconn, &conn_hash->ch_buckets[buckno], cn_next_hash) - if (lconn->cn_cid == cid) - return lconn; - return NULL; -} - - -struct lsquic_conn * -conn_hash_find_by_addr (struct conn_hash *conn_hash, const struct sockaddr *sa) -{ - unsigned char hash_buf[HASHBUF_SZ][2]; - struct lsquic_conn *lconn; - unsigned hash, buckno; - size_t hash_sz[2]; - - sockaddr2hash(sa, hash_buf[0], &hash_sz[0]); - hash = XXH32(hash_buf, hash_sz[0], (uintptr_t) conn_hash); - buckno = conn_hash_bucket_no(conn_hash, hash); - TAILQ_FOREACH(lconn, &conn_hash->ch_buckets[buckno], cn_next_hash) - if (lconn->cn_hash == hash) - { - sockaddr2hash((struct sockaddr *) lconn->cn_local_addr, hash_buf[1], - &hash_sz[1]); - if (hash_sz[0] == hash_sz[1] - && 0 == memcmp(hash_buf[0], hash_buf[1], hash_sz[0])) - return lconn; - } - - return NULL; -} - - -static int -double_conn_hash_buckets (struct conn_hash *conn_hash) -{ - struct lsquic_conn_head *new_buckets, *new[2]; - struct lsquic_conn *lconn; - unsigned n, old_nbits; - int idx; - - old_nbits = conn_hash->ch_nbits; - LSQ_INFO("doubling number of buckets to %u", n_buckets(old_nbits + 1)); - new_buckets = malloc(sizeof(conn_hash->ch_buckets[0]) - * n_buckets(old_nbits + 1)); - if (!new_buckets) - { - LSQ_WARN("malloc failed: potential trouble ahead"); - return -1; - } - - for (n = 0; n < n_buckets(old_nbits); ++n) - { - new[0] = &new_buckets[n]; - new[1] = &new_buckets[n + n_buckets(old_nbits)]; - TAILQ_INIT(new[0]); - TAILQ_INIT(new[1]); - while ((lconn = TAILQ_FIRST(&conn_hash->ch_buckets[n]))) - { - TAILQ_REMOVE(&conn_hash->ch_buckets[n], lconn, cn_next_hash); - idx = (lconn->cn_hash >> old_nbits) & 1; - TAILQ_INSERT_TAIL(new[idx], lconn, cn_next_hash); - } - } - free(conn_hash->ch_buckets); - conn_hash->ch_nbits = old_nbits + 1; - conn_hash->ch_buckets = new_buckets; - return 0; -} - - -int -conn_hash_add (struct conn_hash *conn_hash, struct lsquic_conn *lconn) -{ - unsigned char hash_buf[HASHBUF_SZ]; - const unsigned char *key; - size_t key_sz; - unsigned hash, buckno; - - key = conn_hash->ch_conn2hash(lconn, hash_buf, &key_sz); - hash = XXH32(key, key_sz, (uintptr_t) conn_hash); - if (conn_hash->ch_count >= - n_buckets(conn_hash->ch_nbits) * CONN_HASH_MAX_PER_BUCKET && - conn_hash->ch_nbits < sizeof(hash) * 8 - 1 && - 0 != double_conn_hash_buckets(conn_hash)) - { - return -1; - } - buckno = conn_hash_bucket_no(conn_hash, hash); - lconn->cn_hash = hash; - TAILQ_INSERT_TAIL(&conn_hash->ch_buckets[buckno], lconn, cn_next_hash); - ++conn_hash->ch_count; - return 0; -} - - -void -conn_hash_remove (struct conn_hash *conn_hash, struct lsquic_conn *lconn) -{ - const unsigned buckno = conn_hash_bucket_no(conn_hash, lconn->cn_hash); - TAILQ_REMOVE(&conn_hash->ch_buckets[buckno], lconn, cn_next_hash); - --conn_hash->ch_count; -} - - -void -conn_hash_reset_iter (struct conn_hash *conn_hash) -{ - conn_hash->ch_iter.cur_buckno = 0; - conn_hash->ch_iter.next_conn = TAILQ_FIRST(&conn_hash->ch_buckets[0]); -} - - -struct lsquic_conn * -conn_hash_first (struct conn_hash *conn_hash) -{ - conn_hash_reset_iter(conn_hash); - return conn_hash_next(conn_hash); -} - - -struct lsquic_conn * -conn_hash_next (struct conn_hash *conn_hash) -{ - struct lsquic_conn *lconn = conn_hash->ch_iter.next_conn; - while (!lconn) - { - ++conn_hash->ch_iter.cur_buckno; - if (conn_hash->ch_iter.cur_buckno >= n_buckets(conn_hash->ch_nbits)) - return NULL; - lconn = TAILQ_FIRST(&conn_hash->ch_buckets[ - conn_hash->ch_iter.cur_buckno]); - } - if (lconn) - conn_hash->ch_iter.next_conn = TAILQ_NEXT(lconn, cn_next_hash); - return lconn; -} diff --git a/src/liblsquic/lsquic_conn_hash.h b/src/liblsquic/lsquic_conn_hash.h deleted file mode 100644 index 8fba7d5..0000000 --- a/src/liblsquic/lsquic_conn_hash.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ -/* - * lsquic_conn_hash.h -- A hash of connections - */ - -#ifndef LSQUIC_MC_SET_H -#define LSQUIC_MC_SET_H - -#include - -/* Once we reach this many per bucket on average, double the number of - * buckets and redistribute entries. - * - * This value should be a power of two for speed. - */ -#define CONN_HASH_MAX_PER_BUCKET 2 - -struct lsquic_conn; -struct sockaddr; - -TAILQ_HEAD(lsquic_conn_head, lsquic_conn); - -enum conn_hash_flags -{ - CHF_USE_ADDR = 1 << 0, -}; - - -struct conn_hash -{ - struct lsquic_conn_head *ch_buckets; - struct { - unsigned cur_buckno; - struct lsquic_conn *next_conn; - } ch_iter; - unsigned ch_count; - unsigned ch_nbits; - enum conn_hash_flags ch_flags; - const unsigned char * (*ch_conn2hash)(const struct lsquic_conn *, - unsigned char *, size_t *); -}; - -#define conn_hash_count(conn_hash) (+(conn_hash)->ch_count) - -/* Returns -1 if malloc fails */ -int -conn_hash_init (struct conn_hash *, enum conn_hash_flags); - -void -conn_hash_cleanup (struct conn_hash *); - -struct lsquic_conn * -conn_hash_find_by_cid (struct conn_hash *, lsquic_cid_t); - -struct lsquic_conn * -conn_hash_find_by_addr (struct conn_hash *, const struct sockaddr *); - -/* Returns -1 if limit has been reached or if malloc fails */ -int -conn_hash_add (struct conn_hash *, struct lsquic_conn *); - -void -conn_hash_remove (struct conn_hash *, struct lsquic_conn *); - -/* Two ways to use the iterator: - * 1. - * for (conn = conn_hash_first(hash); conn; - * conn = conn_hash_next(hash)) - * { ... } - * - * 2. - * conn_hash_reset_iter(hash); - * while ((conn = conn_hash_next(hash))) - * { ... } - * - */ -void -conn_hash_reset_iter (struct conn_hash *); - -struct lsquic_conn * -conn_hash_first (struct conn_hash *); - -struct lsquic_conn * -conn_hash_next (struct conn_hash *); - -#define conn_hash_using_addr(h) ((h)->ch_flags & CHF_USE_ADDR) - -#endif diff --git a/src/liblsquic/lsquic_parse_Q044.c b/src/liblsquic/lsquic_parse_Q044.c deleted file mode 100644 index 0322589..0000000 --- a/src/liblsquic/lsquic_parse_Q044.c +++ /dev/null @@ -1,215 +0,0 @@ -/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ -/* - * lsquic_parse_Q044.c -- Parsing functions specific to GQUIC Q044 - */ - -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#else -#include -#endif - -#include "lsquic_types.h" -#include "lsquic_packet_common.h" -#include "lsquic_packet_in.h" -#include "lsquic_packet_out.h" -#include "lsquic_parse.h" -#include "lsquic_parse_common.h" -#include "lsquic_version.h" -#include "lsquic.h" -#include "lsquic_parse_gquic_be.h" -#include "lsquic_byteswap.h" -#include "lsquic_conn.h" - -#define LSQUIC_LOGGER_MODULE LSQLM_PARSE -#include "lsquic_logger.h" - - - - -static int -gen_short_pkt_header (const struct lsquic_conn *lconn, - const struct lsquic_packet_out *packet_out, unsigned char *buf, - size_t bufsz) -{ - unsigned packno_len, need; - enum packno_bits bits; - uint32_t packno; - - bits = (packet_out->po_flags >> POBIT_SHIFT) & 0x3; - packno_len = gquic_packno_bits2len(bits); - - need = 1 + 8 /* CID */ + packno_len; - - if (need > bufsz) - return -1; - - *buf++ = 0x30 | bits; - - memcpy(buf, &lconn->cn_cid, 8); - buf += 8; - - packno = packet_out->po_packno; -#if __BYTE_ORDER == __LITTLE_ENDIAN - packno = bswap_32(packno); -#endif - memcpy(buf, (unsigned char *) &packno + 4 - packno_len, packno_len); - - return need; -} - - -static size_t -gquic_Q044_packout_header_size_long (const struct lsquic_conn *lconn, - enum packet_out_flags flags) -{ - return GQUIC_IETF_LONG_HEADER_SIZE; -} - - -static const unsigned char header_type_to_bin[] = { - [HETY_NOT_SET] = 0x00, - [HETY_INITIAL] = 0x7F, - [HETY_RETRY] = 0x7E, - [HETY_HANDSHAKE] = 0x7D, - [HETY_0RTT] = 0x7C, -}; - - -static int -gen_long_pkt_header (const struct lsquic_conn *lconn, - const struct lsquic_packet_out *packet_out, unsigned char *buf, - size_t bufsz) -{ - lsquic_ver_tag_t ver_tag; - unsigned char *p; - uint32_t packno; - size_t need; - - need = gquic_Q044_packout_header_size_long(lconn, packet_out->po_flags); - if (need > bufsz) - { - errno = EINVAL; - return -1; - } - - p = buf; - *p++ = 0x80 | header_type_to_bin[ packet_out->po_header_type ]; - ver_tag = lsquic_ver2tag(lconn->cn_version); - memcpy(p, &ver_tag, sizeof(ver_tag)); - p += sizeof(ver_tag); - - *p++ = 0x50; - - memcpy(p, &lconn->cn_cid, 8); - p += 8; - - packno = packet_out->po_packno; -#if __BYTE_ORDER == __LITTLE_ENDIAN - packno = bswap_32(packno); -#endif - memcpy(p, &packno, 4); - p += 4; - - - assert(need == (unsigned int)(p - buf)); - return p - buf; -} - - -static int -gquic_Q044_gen_reg_pkt_header (const struct lsquic_conn *lconn, - const struct lsquic_packet_out *packet_out, unsigned char *buf, - size_t bufsz) -{ - if (0 == (packet_out->po_flags & PO_LONGHEAD)) - return gen_short_pkt_header(lconn, packet_out, buf, bufsz); - else - return gen_long_pkt_header(lconn, packet_out, buf, bufsz); -} - - -static size_t -gquic_Q044_packout_header_size_short (const struct lsquic_conn *lconn, - enum packet_out_flags flags) -{ - enum packno_bits bits; - size_t sz; - - bits = (flags >> POBIT_SHIFT) & 0x3; - sz = 1; /* Type */ - sz += 8; /* CID */ - sz += gquic_packno_bits2len(bits); - - return sz; -} - - -static size_t -gquic_Q044_packout_header_size (const struct lsquic_conn *lconn, - enum packet_out_flags flags) -{ - if (0 == (flags & PO_LONGHEAD)) - return gquic_Q044_packout_header_size_short(lconn, flags); - else - return gquic_Q044_packout_header_size_long(lconn, flags); -} - - -static size_t -gquic_Q044_packout_size (const struct lsquic_conn *lconn, - const struct lsquic_packet_out *packet_out) -{ - size_t sz; - - if (0 == (packet_out->po_flags & PO_LONGHEAD)) - sz = gquic_Q044_packout_header_size_short(lconn, packet_out->po_flags); - else - sz = gquic_Q044_packout_header_size_long(lconn, packet_out->po_flags); - - sz += packet_out->po_data_sz; - sz += QUIC_PACKET_HASH_SZ; - - return sz; -} - - -const struct parse_funcs lsquic_parse_funcs_gquic_Q044 = -{ - .pf_gen_reg_pkt_header = gquic_Q044_gen_reg_pkt_header, - .pf_parse_packet_in_finish = gquic_be_parse_packet_in_finish, - .pf_gen_stream_frame = gquic_be_gen_stream_frame, - .pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, - .pf_parse_stream_frame = gquic_be_parse_stream_frame, - .pf_parse_ack_frame = gquic_be_parse_ack_frame, - .pf_gen_ack_frame = gquic_be_gen_ack_frame, - .pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, - .pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, - .pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, - .pf_gen_window_update_frame = gquic_be_gen_window_update_frame, - .pf_parse_window_update_frame = gquic_be_parse_window_update_frame, - .pf_gen_blocked_frame = gquic_be_gen_blocked_frame, - .pf_parse_blocked_frame = gquic_be_parse_blocked_frame, - .pf_gen_rst_frame = gquic_be_gen_rst_frame, - .pf_parse_rst_frame = gquic_be_parse_rst_frame, - .pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, - .pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, - .pf_gen_goaway_frame = gquic_be_gen_goaway_frame, - .pf_parse_goaway_frame = gquic_be_parse_goaway_frame, - .pf_gen_ping_frame = gquic_be_gen_ping_frame, -#ifndef NDEBUG - .pf_write_float_time16 = gquic_be_write_float_time16, - .pf_read_float_time16 = gquic_be_read_float_time16, -#endif - .pf_parse_frame_type = parse_frame_type_gquic_Q035_thru_Q039, - .pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q039, - .pf_packout_size = gquic_Q044_packout_size, - .pf_packout_header_size = gquic_Q044_packout_header_size, - .pf_calc_packno_bits = lsquic_gquic_calc_packno_bits, - .pf_packno_bits2len = lsquic_gquic_packno_bits2len, -}; diff --git a/src/liblsquic/lsquic_parse_gquic_le.c b/src/liblsquic/lsquic_parse_gquic_le.c deleted file mode 100644 index 870f5d7..0000000 --- a/src/liblsquic/lsquic_parse_gquic_le.c +++ /dev/null @@ -1,851 +0,0 @@ -/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ -/* - * lsquic_parse_gquic_le.c -- Parsing functions specific to little-endian - * (Q038 and lower) GQUIC. - */ - -#include -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#else -#include -#endif - -#include "lsquic_types.h" -#include "lsquic_alarmset.h" -#include "lsquic_packet_common.h" -#include "lsquic_packet_in.h" -#include "lsquic_packet_out.h" -#include "lsquic_parse.h" -#include "lsquic_parse_common.h" -#include "lsquic_rechist.h" -#include "lsquic_sfcw.h" -#include "lsquic_stream.h" -#include "lsquic_mm.h" -#include "lsquic_malo.h" -#include "lsquic_version.h" -#include "lsquic.h" -#include "lsquic_conn.h" - -#define LSQUIC_LOGGER_MODULE LSQLM_PARSE -#include "lsquic_logger.h" - -#define CHECK_SPACE(need, pstart, pend) \ - do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0) - -/* get the len bytes as a uint64_t */ -static uint64_t get_vary_len_int64(const void *mem, uint8_t len) -{ - assert(len <= 8); - uint64_t v = 0; - memcpy(&v, mem, len); - return v; -} - - -static void write_vary_len_to_buf(uint64_t v, unsigned char *mem, uint8_t len) -{ - assert(len <= 8); - memcpy(mem, &v, len); -} - - -/* read 16 bits(2 bytes) time, unit: us */ -static uint64_t -gquic_le_read_float_time16 (const void *mem) -{ - uint64_t temp = get_vary_len_int64(mem, 2); - uint16_t exp = (temp >> 11) & 0x1F; - if (0 == exp) - return temp; - else - { - --exp; - temp &= 0x7FF; - temp |= 0x800; - return temp << exp; - } -} - - -static void -gquic_le_write_float_time16 (lsquic_time_t time_us, void *mem) -{ - uint16_t ret = 0; - uint16_t high, i; - - if (time_us < ((uint64_t)1 << 11)) - ret = time_us; - else if(time_us > 0x3FFC0000000) - ret = 0xFFFF; - else - { - high = 0; - for (i = 16; i > 0; i /= 2) - { - if (time_us >= (uint64_t)1 << (11 + i)) - { - high |= i; - time_us >>= i; - } - } - ret = time_us + (high << 11); - } - memcpy(mem, (void *)&ret, 2); -} - - -static int packet_length_arr[] = {1, 2, 4, 6}; - -/* make sure the flag is lower 2 bits set for this checking */ -static int -flag_to_pkt_num_len(unsigned char flag) -{ - return packet_length_arr[flag & 0x03]; -} - - -/* Parse out packet number */ -static void -gquic_le_parse_packet_in_finish (lsquic_packet_in_t *packet_in, - struct packin_parse_state *state) -{ - if (state->pps_nbytes) - memcpy((void *)&packet_in->pi_packno, state->pps_p, state->pps_nbytes); -} - - -static int -gquic_le_gen_reg_pkt_header (const struct lsquic_conn *lconn, - const struct lsquic_packet_out *packet_out, unsigned char *buf, - size_t bufsz) -{ - unsigned packnum_len, header_len; - unsigned char *p; - enum packno_bits bits; - - bits = lsquic_packet_out_packno_bits(packet_out); - packnum_len = gquic_packno_bits2len(bits); - - header_len = 1 - + (!!(packet_out->po_flags & PO_CONN_ID) << 3) - + (!!(packet_out->po_flags & PO_VERSION) << 2) - + (!!(packet_out->po_flags & PO_NONCE) << 5) - + packnum_len - ; - if (header_len > bufsz) - { - errno = ENOBUFS; - return -1; - } - - p = buf; - - *p = (!!(packet_out->po_flags & PO_CONN_ID) << 3) - | (bits << 4) - | ((!!(packet_out->po_flags & PO_NONCE)) << 2) - | !!(packet_out->po_flags & PO_VERSION); - ++p; - - if (packet_out->po_flags & PO_CONN_ID) - { - memcpy(p, &lconn->cn_cid, sizeof(lconn->cn_cid)); - p += sizeof(lconn->cn_cid); - } - - if (packet_out->po_flags & PO_VERSION) - { - memcpy(p, &packet_out->po_ver_tag, 4); - p += 4; - } - - if (packet_out->po_flags & PO_NONCE) - { - memcpy(p, packet_out->po_nonce, 32); - p += 32; - } - - /* ENDIAN */ - memcpy(p, &packet_out->po_packno, packnum_len); - p += packnum_len; - - assert(p - buf == (intptr_t) header_len); - - return header_len; -} - - -static int -gquic_le_gen_stream_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id, - uint64_t offset, int fin, size_t size, - gsf_read_f gsf_read, void *stream) -{ - /* 1fdoooss */ - unsigned slen, olen, dlen; - unsigned char *p = buf + 1; - - /* ss: Stream ID length: 1, 2, 3, or 4 bytes */ - slen = (stream_id > 0x0000FF) - + (stream_id > 0x00FFFF) - + (stream_id > 0xFFFFFF) - + 1; - - /* ooo: Offset length: 0, 2, 3, 4, 5, 6, 7, or 8 bytes */ - olen = (offset >= (1ULL << 56)) - + (offset >= (1ULL << 48)) - + (offset >= (1ULL << 40)) - + (offset >= (1ULL << 32)) - + (offset >= (1ULL << 24)) - + (offset >= (1ULL << 16)) - + ((offset > 0) << 1); - - if (!fin) - { - unsigned n_avail; - uint16_t nr; - - n_avail = buf_len - (p + slen + olen - buf); - - /* If we cannot fill remaining buffer, we need to include data - * length. - */ - dlen = (size < n_avail) << 1; - n_avail -= dlen; - - CHECK_STREAM_SPACE(1 + olen + slen + dlen + - + 1 /* We need to write at least 1 byte */, buf, buf + buf_len); - - memcpy(p, &stream_id, slen); - p += slen; - - memcpy(p, &offset, olen); - p += olen; - - /* Read as much as we can */ - nr = gsf_read(stream, p + dlen, n_avail, &fin); - assert(nr != 0); - - if (dlen) - memcpy(p, &nr, 2); - - p += dlen + nr; - } - else - { - dlen = 2; - CHECK_STREAM_SPACE(1 + slen + olen + 2, buf, buf + buf_len); - memcpy(p, &stream_id, slen); - p += slen; - memcpy(p, &offset, olen); - p += olen; - memset(p, 0, 2); - p += 2; - } - - /* Convert slen to bit representation: 0 - 3: */ - slen -= 1; - assert(slen <= 3); - - /* Convert olen to bit representation: 0 - 7: */ - olen += !olen; - olen -= 1; - assert(olen <= 7); - - buf[0] = 0x80 - | (fin << 6) - | (dlen << 4) - | (olen << 2) - | slen - ; - return p - buf; -} - - -/* return parsed (used) buffer length */ -static int -gquic_le_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz, - stream_frame_t *stream_frame) -{ - /* 1fdoooss */ - const unsigned char *p = buf; - const unsigned char *const pend = p + rem_packet_sz; - - CHECK_SPACE(1, p, pend); - const char type = *p++; - - const unsigned data_len = (type >> 4) & 2; - const unsigned offset_len = ((type >> 2) & 7) + 1 - !((type >> 2) & 7); - const unsigned stream_id_len = 1 + (type & 3); - const unsigned need = data_len + offset_len + stream_id_len; - CHECK_SPACE(need, p, pend); - - memset(stream_frame, 0, sizeof(*stream_frame)); - - stream_frame->data_frame.df_fin = (type >> 6) & 1; - - memcpy(&stream_frame->stream_id, p, stream_id_len); - p += stream_id_len; - - memcpy(&stream_frame->data_frame.df_offset, p, offset_len); - p += offset_len; - - if (data_len) - { - memcpy(&stream_frame->data_frame.df_size, p, data_len); - p += data_len; - CHECK_SPACE(stream_frame->data_frame.df_size, p, pend); - stream_frame->data_frame.df_data = p; - p += stream_frame->data_frame.df_size; - } - else - { - stream_frame->data_frame.df_size = pend - p; - stream_frame->data_frame.df_data = p; - p = pend; - } - - /* From the spec: "A stream frame must always have either non-zero - * data length or the FIN bit set.' - */ - if (!(stream_frame->data_frame.df_size || - stream_frame->data_frame.df_fin)) - return -1; - - assert(p <= pend); - - return p - (unsigned char *) buf; -} - - -/* Return parsed (used) buffer length. - * If parsing failed, negative value is returned. - */ -static int -gquic_le_parse_ack_frame (const unsigned char *buf, size_t buf_len, ack_info_t *ack) -{ - /* 01nullmm */ - const unsigned char type = buf[0]; - const unsigned char *p = buf + 1; - const unsigned char *const pend = buf + buf_len; - - assert((type & 0xC0) == 0x40); /* We're passed correct frame type */ - - const int ack_block_len = flag_to_pkt_num_len(type); /* mm */ - const int largest_obs_len = flag_to_pkt_num_len(type >> 2); /* ll */ - - CHECK_SPACE(largest_obs_len, p , pend); - - ack->ranges[0].high = get_vary_len_int64(p, largest_obs_len); - p += largest_obs_len; - - CHECK_SPACE(2, p , pend); - ack->lack_delta = gquic_le_read_float_time16(p); - p += 2; - - unsigned n_blocks; - if (type & 0x20) - { - CHECK_SPACE(1, p , pend); - n_blocks = *p; - ++p; - } - else - n_blocks = 0; - - CHECK_SPACE(ack_block_len, p , pend); - ack->ranges[0].low = ack->ranges[0].high - - get_vary_len_int64(p, ack_block_len) + 1; - p += ack_block_len; - - if (n_blocks) - { - CHECK_SPACE((ack_block_len + 1) * n_blocks, p , pend); - unsigned i, n, gap; - for (i = 0, n = 1, gap = 0; i < n_blocks; ++i) - { - gap += *p; - const uint64_t length = get_vary_len_int64(p + 1, ack_block_len); - p += 1 + ack_block_len; - if (length) - { - ack->ranges[n].high = ack->ranges[n - 1].low - gap - 1; - ack->ranges[n].low = ack->ranges[n].high - length + 1; - ++n; - gap = 0; - } - } - ack->n_ranges = n; - } - else - ack->n_ranges = 1; - - CHECK_SPACE(1, p , pend); - ack->n_timestamps = *p; - ++p; - - if (ack->n_timestamps) - { -#if LSQUIC_PARSE_ACK_TIMESTAMPS - CHECK_SPACE(5, p , pend); - ack->timestamps[0].packet_delta = *p++; - memcpy(&ack->timestamps[0].delta_usec, p, 4); - p += 4; - unsigned i; - for (i = 1; i < ack->n_timestamps; ++i) - { - CHECK_SPACE(3, p , pend); - ack->timestamps[i].packet_delta = *p++; - uint64_t delta_time = read_float_time16(p); - p += 2; - ack->timestamps[i].delta_usec = - ack->timestamps[i - 1].delta_usec + delta_time; - } -#else - unsigned timestamps_size = 5 + 3 * (ack->n_timestamps - 1); - CHECK_SPACE(timestamps_size, p, pend); - p += timestamps_size; -#endif - } - - assert(p <= pend); - - return p - (unsigned char *) buf; -} - - -static int -gquic_le_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len, - lsquic_packno_t cur_packno, enum packno_bits bits, - lsquic_packno_t least_unacked_packno) -{ - lsquic_packno_t delta; - unsigned packnum_len = gquic_packno_bits2len(bits); - - if (buf_len >= 1 + packnum_len) - { - *buf = 0x06; - delta = cur_packno - least_unacked_packno; - write_vary_len_to_buf(delta, buf + 1, packnum_len); - return 1 + packnum_len; - } - else - return -1; -} - - -static int -gquic_le_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len, - lsquic_packno_t cur_packno, enum packno_bits bits, - lsquic_packno_t *least_unacked) -{ - lsquic_packno_t delta; - unsigned packnum_len = gquic_packno_bits2len(bits); - - if (buf_len >= 1 + packnum_len) - { - delta = 0; - memcpy(&delta, buf + 1, packnum_len); - *least_unacked = cur_packno - delta; - return 1 + packnum_len; - } - else - return -1; -} - - -static int -gquic_le_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits) -{ - unsigned packnum_len = gquic_packno_bits2len(bits); - if (buf_len >= 1 + packnum_len) - return 1 + packnum_len; - else - return -1; -} - - -static int -gquic_le_gen_window_update_frame (unsigned char *buf, int buf_len, uint32_t stream_id, - uint64_t offset) -{ - unsigned char *p = buf; - if (buf_len < QUIC_WUF_SZ) - return -1; - - *p = 0x04; - ++p; - write_vary_len_to_buf(stream_id, p, 4); - p += 4; - write_vary_len_to_buf(offset, p, 8); - p += 8; - return p - buf; -} - - -static int -gquic_le_parse_window_update_frame (const unsigned char *buf, size_t buf_len, - uint32_t *stream_id, uint64_t *offset) -{ - if (buf_len < QUIC_WUF_SZ) - return -1; - - *stream_id = get_vary_len_int64(buf + 1, 4); - *offset = get_vary_len_int64(buf + 1 + 4, 8); - return QUIC_WUF_SZ; -} - - -static int -gquic_le_gen_blocked_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id) -{ - unsigned char *p = buf; - if (buf_len < QUIC_BLOCKED_FRAME_SZ) - return -1; - - *p = 0x05; - ++p; - write_vary_len_to_buf(stream_id, p, 4); - p += 4; - return p - buf; -} - - -static int -gquic_le_parse_blocked_frame (const unsigned char *buf, size_t buf_len, - uint32_t *stream_id) -{ - if (buf_len < QUIC_BLOCKED_FRAME_SZ) - return -1; - - *stream_id = get_vary_len_int64(buf + 1, 4); - return QUIC_BLOCKED_FRAME_SZ; -} - - -static int -gquic_le_gen_rst_frame (unsigned char *buf, size_t buf_len, uint32_t stream_id, - uint64_t offset, uint32_t error_code) -{ - unsigned char *p = buf; - if (buf_len < QUIC_RST_STREAM_SZ) - return -1; - - *p = 0x01; - ++p; - write_vary_len_to_buf(stream_id, p, 4); - p += 4; - write_vary_len_to_buf(offset, p, 8); - p += 8; - write_vary_len_to_buf(error_code, p, 4); - p += 4; - return p - buf; -} - - -static int -gquic_le_parse_rst_frame (const unsigned char *buf, size_t buf_len, uint32_t *stream_id, - uint64_t *offset, uint32_t *error_code) -{ - if (buf_len < 17) - return -1; - - *stream_id = get_vary_len_int64(buf + 1, 4); - *offset = get_vary_len_int64(buf + 1 + 4, 8); - *error_code = get_vary_len_int64(buf + 1 + 4 + 8, 4); - return 17; -} - - -static int -gquic_le_gen_ping_frame (unsigned char *buf, int buf_len) -{ - if (buf_len > 0) - { - buf[0] = 0x07; - return 1; - } - else - return -1; -} - - -static int -gquic_le_gen_connect_close_frame (unsigned char *buf, int buf_len, uint32_t error_code, - const char *reason, int reason_len) -{ - unsigned char *p = buf; - if (buf_len < 7) - return -1; - - *p = 0x02; - ++p; - write_vary_len_to_buf(error_code, p, 4); - p += 4; - write_vary_len_to_buf(reason_len, p, 2); - p += 2; - memcpy(p, reason, reason_len); - p += reason_len; - if (buf_len < p - buf) - return -2; - - return p - buf; -} - - -static int -gquic_le_parse_connect_close_frame (const unsigned char *buf, size_t buf_len, - uint32_t *error_code, uint16_t *reason_len, uint8_t *reason_offset) -{ - if (buf_len < 7) - return -1; - - *error_code = get_vary_len_int64(buf + 1, 4); - *reason_len = get_vary_len_int64(buf + 1 + 4, 2); - *reason_offset = 7; - if (buf_len < 7u + *reason_len) - return -2; - - return 7 + *reason_len; -} - - -static int -gquic_le_gen_goaway_frame(unsigned char *buf, size_t buf_len, uint32_t error_code, - uint32_t last_good_stream_id, const char *reason, - size_t reason_len) -{ - unsigned char *p = buf; - if (buf_len < QUIC_GOAWAY_FRAME_SZ + reason_len) - return -1; - - *p = 0x03; - ++p; - write_vary_len_to_buf(error_code, p, 4); - p += 4; - write_vary_len_to_buf(last_good_stream_id, p, 4); - p += 4; - write_vary_len_to_buf(reason_len, p, 2); - p += 2; - if (reason_len) - { - memcpy(p, reason, reason_len); - p += reason_len; - } - - return p - buf; -} - - -/* the reason is buf + *reason_offset, length is *reason_length */ -static int -gquic_le_parse_goaway_frame (const unsigned char *buf, size_t buf_len, - uint32_t *error_code, uint32_t *last_good_stream_id, - uint16_t *reason_length, const char **reason) -{ - if (buf_len < QUIC_GOAWAY_FRAME_SZ) - return -1; - - *error_code = get_vary_len_int64(buf + 1, 4); - *last_good_stream_id = get_vary_len_int64(buf + 1 + 4, 4); - *reason_length = get_vary_len_int64(buf + 1 + 4 + 4, 2); - if (*reason_length) - { - if ((int)buf_len < QUIC_GOAWAY_FRAME_SZ + *reason_length) - return -2; - *reason = (const char *) buf + QUIC_GOAWAY_FRAME_SZ; - } - else - *reason = NULL; - - return QUIC_GOAWAY_FRAME_SZ + *reason_length; -} - - -/* Returns number of bytes written or -1 on failure */ -/* This function makes an assumption that there is at least one range */ -static int -gquic_le_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz, - gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next, - gaf_rechist_largest_recv_f rechist_largest_recv, - void *rechist, lsquic_time_t now, int *has_missing, - lsquic_packno_t *largest_received) -{ - lsquic_time_t time_diff; - const struct lsquic_packno_range *const first = rechist_first(rechist); - if (!first) - { - errno = EINVAL; - return -1; - } - - /* Copy values from the first range, because the memory the pointer - * points to may change: - */ - const lsquic_packno_t first_low = first->low, first_high = first->high; - - unsigned char *p = outbuf; - unsigned char *const type = p; - unsigned char *const end = p + outbuf_sz; - -#define AVAIL() (end - p) - -#define CHECKOUT(sz) do { \ - if ((intptr_t) (sz) > AVAIL()) { \ - errno = ENOBUFS; \ - return -1; \ - } \ -} while (0) - - CHECKOUT(1); - ++p; - - /* 01nullmm */ - *type = 0x40; - - unsigned largest_acked_len, ack_block_len, bits; - - /* Calculate largest ACKed len and set `ll' bits: */ - const lsquic_packno_t maxno = first_high; - bits = (maxno >= (1ULL << 8)) - + (maxno >= (1ULL << 16)) - + (maxno >= (1ULL << 32)); - largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1); - *type |= bits << 2; - - /* Calculate largest ACK block length and set `mm' bits: */ - unsigned n_ranges = 0; - lsquic_packno_t maxdiff = 0; - const struct lsquic_packno_range *range; - for (range = rechist_first(rechist); range; range = rechist_next(rechist)) - { - ++n_ranges; - const lsquic_packno_t diff = range->high - range->low + 1; - if (diff > maxdiff) - maxdiff = diff; - } - bits = (maxdiff >= (1ULL << 8)) - + (maxdiff >= (1ULL << 16)) - + (maxdiff >= (1ULL << 32)); - ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1); - *type |= bits; - - CHECKOUT(largest_acked_len); - memcpy(p, &maxno, largest_acked_len); - p += largest_acked_len; - - CHECKOUT(2); - time_diff = now - rechist_largest_recv(rechist); - gquic_le_write_float_time16(time_diff, p); - LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff, - *(uint16_t*)p); - p += 2; - - if (n_ranges > 1) - { - *has_missing = 1; - *type |= 0x20; - /* We need to write out at least one range */ - CHECKOUT(2 * (1 + ack_block_len)); - unsigned char *const n_ranges_p = p; /* Set this later */ - lsquic_packno_t diff = maxno - first_low + 1; - memcpy(p + 1, &diff, ack_block_len); - p += ack_block_len + 1; - /* Write out ack blocks until one of the following occurs: - * 1. We run out of intervals. - * 2. We run out of room. - * 3. We run out of highest possible number of ACK blocks (0xFF). - */ - range = rechist_first(rechist); - lsquic_packno_t gap = 0; - n_ranges = 0; - do { - if (0 == gap) - { - const lsquic_packno_t prev_low = range->low; - range = rechist_next(rechist); - if (!range) - break; - gap = prev_low - range->high - 1; - } - if (gap >= 0x100) - { - *p = 0xFF; - gap -= 0xFF; - memset(p + 1, 0, ack_block_len); - } - else - { - *p = gap; - gap = 0; - diff = range->high - range->low + 1; - memcpy(p + 1, &diff, ack_block_len); - } - p += ack_block_len + 1; - ++n_ranges; - } while (n_ranges < 0xFF && - AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */); - *n_ranges_p = n_ranges; - } - else - { - *has_missing = 0; - CHECKOUT(ack_block_len); - const lsquic_packno_t diff = maxno - first_low + 1; - memcpy(p, &diff, ack_block_len); - p += ack_block_len; - } - - /* We do not generate timestamp list because the reference implementation - * does not use them. When that changes, we will start sending timestamps - * over. - */ - CHECKOUT(1); - *p = 0; - ++p; - - *largest_received = maxno; - return p - (unsigned char *) outbuf; - -#undef CHECKOUT -} - - -const struct parse_funcs lsquic_parse_funcs_gquic_le = -{ - .pf_gen_reg_pkt_header = gquic_le_gen_reg_pkt_header, - .pf_parse_packet_in_finish = gquic_le_parse_packet_in_finish, - .pf_gen_stream_frame = gquic_le_gen_stream_frame, - .pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, - .pf_parse_stream_frame = gquic_le_parse_stream_frame, - .pf_parse_ack_frame = gquic_le_parse_ack_frame, - .pf_gen_ack_frame = gquic_le_gen_ack_frame, - .pf_gen_stop_waiting_frame = gquic_le_gen_stop_waiting_frame, - .pf_parse_stop_waiting_frame = gquic_le_parse_stop_waiting_frame, - .pf_skip_stop_waiting_frame = gquic_le_skip_stop_waiting_frame, - .pf_gen_window_update_frame = gquic_le_gen_window_update_frame, - .pf_parse_window_update_frame = gquic_le_parse_window_update_frame, - .pf_gen_blocked_frame = gquic_le_gen_blocked_frame, - .pf_parse_blocked_frame = gquic_le_parse_blocked_frame, - .pf_gen_rst_frame = gquic_le_gen_rst_frame, - .pf_parse_rst_frame = gquic_le_parse_rst_frame, - .pf_gen_connect_close_frame = gquic_le_gen_connect_close_frame, - .pf_parse_connect_close_frame = gquic_le_parse_connect_close_frame, - .pf_gen_goaway_frame = gquic_le_gen_goaway_frame, - .pf_parse_goaway_frame = gquic_le_parse_goaway_frame, - .pf_gen_ping_frame = gquic_le_gen_ping_frame, -#ifndef NDEBUG - .pf_write_float_time16 = gquic_le_write_float_time16, - .pf_read_float_time16 = gquic_le_read_float_time16, -#endif - .pf_parse_frame_type = parse_frame_type_gquic_Q035_thru_Q039, - .pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q039, - .pf_packout_size = lsquic_gquic_packout_size, - .pf_packout_header_size = lsquic_gquic_packout_header_size, - .pf_calc_packno_bits = lsquic_gquic_calc_packno_bits, - .pf_packno_bits2len = lsquic_gquic_packno_bits2len, -};