lsquic_packet_common.c revision 50aadb33
1/* Copyright (c) 2017 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 13static const char * const frame_type_2_str[N_QUIC_FRAMES] = { 14 [QUIC_FRAME_INVALID] = "QUIC_FRAME_INVALID", 15 [QUIC_FRAME_STREAM] = "QUIC_FRAME_STREAM", 16 [QUIC_FRAME_ACK] = "QUIC_FRAME_ACK", 17 [QUIC_FRAME_PADDING] = "QUIC_FRAME_PADDING", 18 [QUIC_FRAME_RST_STREAM] = "QUIC_FRAME_RST_STREAM", 19 [QUIC_FRAME_CONNECTION_CLOSE] = "QUIC_FRAME_CONNECTION_CLOSE", 20 [QUIC_FRAME_GOAWAY] = "QUIC_FRAME_GOAWAY", 21 [QUIC_FRAME_WINDOW_UPDATE] = "QUIC_FRAME_WINDOW_UPDATE", 22 [QUIC_FRAME_BLOCKED] = "QUIC_FRAME_BLOCKED", 23 [QUIC_FRAME_STOP_WAITING] = "QUIC_FRAME_STOP_WAITING", 24 [QUIC_FRAME_PING] = "QUIC_FRAME_PING", 25}; 26 27 28#define SLEN(x) (sizeof(#x) - sizeof("QUIC_FRAME_")) 29 30 31const size_t lsquic_frame_types_str_sz = 32 /* We don't need to include INVALID frame in this list because it is 33 * never a part of any frame list bitmask (e.g. po_frame_types). 34 */ 35 SLEN(QUIC_FRAME_STREAM) + 1 + 36 SLEN(QUIC_FRAME_ACK) + 1 + 37 SLEN(QUIC_FRAME_PADDING) + 1 + 38 SLEN(QUIC_FRAME_RST_STREAM) + 1 + 39 SLEN(QUIC_FRAME_CONNECTION_CLOSE) + 1 + 40 SLEN(QUIC_FRAME_GOAWAY) + 1 + 41 SLEN(QUIC_FRAME_WINDOW_UPDATE) + 1 + 42 SLEN(QUIC_FRAME_BLOCKED) + 1 + 43 SLEN(QUIC_FRAME_STOP_WAITING) + 1 + 44 SLEN(QUIC_FRAME_PING) + 1; 45 46 47const char * 48lsquic_frame_types_to_str (char *buf, size_t bufsz, short frame_types) 49{ 50 char *p; 51 int i, w; 52 size_t sz; 53 54 if (bufsz > 0) 55 buf[0] = '\0'; 56 57 p = buf; 58 for (i = 0; i < N_QUIC_FRAMES; ++i) 59 { 60 if (frame_types & (1 << i)) 61 { 62 sz = bufsz - (p - buf); 63 w = snprintf(p, sz, "%.*s%s", p > buf, " ", 64 frame_type_2_str[i] + sizeof("QUIC_FRAME_") - 1); 65 if (w > (int) sz) 66 { 67 LSQ_WARN("not enough room for all frame types"); 68 break; 69 } 70 p += w; 71 } 72 frame_types &= ~(1 << i); 73 } 74 75 return buf; 76} 77 78 79enum lsquic_packno_bits 80calc_packno_bits (lsquic_packno_t packno, lsquic_packno_t least_unacked, 81 uint64_t n_in_flight) 82{ 83 uint64_t delta; 84 unsigned bits; 85 86 delta = packno - least_unacked; 87 if (n_in_flight > delta) 88 delta = n_in_flight; 89 90 delta *= 4; 91 bits = (delta > (1ULL << 8)) 92 + (delta > (1ULL << 16)) 93 + (delta > (1ULL << 32)); 94 95 return bits; 96} 97 98 99lsquic_packno_t 100restore_packno (lsquic_packno_t cur_packno, 101 enum lsquic_packno_bits cur_packno_bits, 102 lsquic_packno_t max_packno) 103{ 104 lsquic_packno_t candidates[3], epoch_delta; 105 int64_t diffs[3]; 106 unsigned min, len; 107 108 len = packno_bits2len(cur_packno_bits); 109 epoch_delta = 1ULL << (len << 3); 110 candidates[1] = (max_packno & ~(epoch_delta - 1)) + cur_packno; 111 candidates[0] = candidates[1] - epoch_delta; 112 candidates[2] = candidates[1] + epoch_delta; 113 114 diffs[0] = llabs((int64_t) candidates[0] - (int64_t) max_packno); 115 diffs[1] = llabs((int64_t) candidates[1] - (int64_t) max_packno); 116 diffs[2] = llabs((int64_t) candidates[2] - (int64_t) max_packno); 117 118 min = diffs[1] < diffs[0]; 119 if (diffs[2] < diffs[min]) 120 min = 2; 121 122 return candidates[min]; 123} 124