1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#ifndef WIN32 7#include <sys/time.h> 8#endif 9#include <sys/queue.h> 10 11#include "lsquic_types.h" 12#include "lsquic.h" 13#include "lsquic_int_types.h" 14#include "lsquic_packet_common.h" 15#include "lsquic_packet_out.h" 16#include "lsquic_hash.h" 17#include "lsquic_conn.h" 18#include "lsquic_parse.h" 19 20struct test { 21 /* Inputs. */ 22 const struct parse_funcs 23 *pf; 24 size_t bufsz; 25 uint64_t cid; /* Zero means connection ID is not specified */ 26 const char *nonce; 27 lsquic_packno_t packno; 28 enum packno_bits 29 bits; /* The test has been retrofitted by adding bits parameter. The test can 30 * be made more complicated by calculating packet number length based on 31 * some other inputs. However, this is tested elsewhere. 32 */ 33 union { 34 unsigned char buf[4]; 35 lsquic_ver_tag_t val; 36 } ver; 37 38 /* Outputs */ 39 int len; /* Retval */ 40 char out[0x100]; /* Contents */ 41}; 42 43 44static void 45run_test (const struct test *const test) 46{ 47 48 struct lsquic_packet_out packet_out = 49 { 50 .po_flags = (test->cid ? PO_CONN_ID : 0) 51 | (test->ver.val ? PO_VERSION : 0) 52 | (test->nonce ? PO_NONCE: 0) 53 , 54 .po_nonce = (unsigned char *) test->nonce, 55 .po_ver_tag = test->ver.val, 56 .po_packno = test->packno, 57 }; 58 lsquic_packet_out_set_packno_bits(&packet_out, test->bits); 59 60 lsquic_cid_t cid; 61 memset(&cid, 0, sizeof(cid)); 62 cid.len = sizeof(test->cid); 63 memcpy(cid.idbuf, &test->cid, sizeof(test->cid)); 64 65 struct lsquic_conn lconn = LSCONN_INITIALIZER_CID(lconn, cid); 66 67 unsigned char out[GQUIC_MAX_PUBHDR_SZ]; 68 int len = test->pf->pf_gen_reg_pkt_header(&lconn, &packet_out, out, 69 sizeof(out), NULL, NULL); 70 71 assert(("Packet length is correct", len == test->len)); 72 73 if (test->len > 0) 74 assert(("Packet contents are correct", 75 0 == memcmp(out, test->out, len))); 76} 77 78 79int 80main (void) 81{ 82 const struct test tests[] = { 83 { 84 .pf = select_pf_by_ver(LSQVER_043), 85 .bufsz = GQUIC_MAX_PUBHDR_SZ, 86 .cid = 0x0102030405060708UL, 87 .nonce = NULL, 88 .packno = 0x01020304, 89 .bits = GQUIC_PACKNO_LEN_4, 90 .len = 1 + 8 + 0 + 4, 91 .out = { (0 << 2) /* Nonce present */ 92 | 0x08 /* Connection ID present */ 93 | 0x20 /* Packet number length */ 94 , 95 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 96 0x01, 0x02, 0x03, 0x04, /* Packet number */ 97 }, 98 }, 99 100 { 101 .pf = select_pf_by_ver(LSQVER_043), 102 .bufsz = GQUIC_MAX_PUBHDR_SZ, 103 .cid = 0x0102030405060708UL, 104 .nonce = NULL, 105 .packno = 0x00, 106 .bits = GQUIC_PACKNO_LEN_1, 107 .len = 1 + 8 + 0 + 1, 108 .out = { (0 << 2) /* Nonce present */ 109 | 0x08 /* Connection ID present */ 110 | 0x00 /* Packet number length */ 111 , 112 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 113 0x00, /* Packet number */ 114 }, 115 }, 116 117 { 118 .pf = select_pf_by_ver(LSQVER_043), 119 .bufsz = GQUIC_MAX_PUBHDR_SZ, 120 .cid = 0x0102030405060708UL, 121 .nonce = NULL, 122 .packno = 0x09, 123 .bits = GQUIC_PACKNO_LEN_1, 124 .ver.buf= { 'Q', '0', '4', '3', }, 125 .len = 1 + 8 + 4 + 0 + 1, 126 .out = { (0 << 2) /* Nonce present */ 127 | 0x01 /* Version present */ 128 | 0x08 /* Connection ID present */ 129 | 0x00 /* Packet number length */ 130 , 131 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 132 'Q', '0', '4', '3', 133 0x09, /* Packet number */ 134 }, 135 }, 136 137 #define NONCENSE "0123456789abcdefghijklmnopqrstuv" 138 #define NONCENSE_BYTES '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v' 139 140 { 141 .pf = select_pf_by_ver(LSQVER_043), 142 .bufsz = GQUIC_MAX_PUBHDR_SZ, 143 .cid = 0x0102030405060708UL, 144 .nonce = NONCENSE, 145 .packno = 0x00, 146 .bits = GQUIC_PACKNO_LEN_1, 147 .len = 1 + 8 + 32 + 1, 148 .out = { (1 << 2) /* Nonce present */ 149 | 0x08 /* Connection ID present */ 150 | 0x00 /* Packet number length */ 151 , 152 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 153 NONCENSE_BYTES, 154 0x00, /* Packet number */ 155 }, 156 }, 157 158 { 159 .pf = select_pf_by_ver(LSQVER_043), 160 .bufsz = GQUIC_MAX_PUBHDR_SZ, 161 .cid = 0, /* Do not set connection ID */ 162 .nonce = NONCENSE, 163 .packno = 0x00, 164 .bits = GQUIC_PACKNO_LEN_1, 165 .len = 1 + 0 + 32 + 1, 166 .out = { (1 << 2) /* Nonce present */ 167 | 0x00 /* Packet number length */ 168 , 169 NONCENSE_BYTES, 170 0x00, /* Packet number */ 171 }, 172 }, 173 174 { 175 .pf = select_pf_by_ver(LSQVER_043), 176 .bufsz = GQUIC_MAX_PUBHDR_SZ, 177 .cid = 0x0102030405060708UL, 178 .nonce = NONCENSE, 179 .packno = 0x00, 180 .bits = GQUIC_PACKNO_LEN_1, 181 .ver.buf= { 'Q', '0', '4', '3', }, 182 .len = 1 + 8 + 4 + 32 + 1, 183 .out = { (1 << 2) /* Nonce present */ 184 | 0x01 /* Version present */ 185 | 0x08 /* Connection ID present */ 186 | 0x00 /* Packet number length */ 187 , 188 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 189 'Q', '0', '4', '3', 190 NONCENSE_BYTES, 191 0x00, /* Packet number */ 192 }, 193 }, 194 195 { 196 .pf = select_pf_by_ver(LSQVER_043), 197 .bufsz = GQUIC_MAX_PUBHDR_SZ, 198 .cid = 0x0102030405060708UL, 199 .nonce = NONCENSE, 200 .packno = 0xA0A1A2A3A4A5A6A7UL, 201 .bits = GQUIC_PACKNO_LEN_6, 202 .len = 1 + 8 + 32 + 6, 203 .out = { (1 << 2) /* Nonce present */ 204 | 0x08 /* Connection ID present */ 205 | 0x30 /* Packet number length */ 206 , 207 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 208 NONCENSE_BYTES, 209 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 210 }, 211 }, 212 213 { 214 .pf = select_pf_by_ver(LSQVER_043), 215 .bufsz = GQUIC_MAX_PUBHDR_SZ, 216 .cid = 0x0102030405060708UL, 217 .nonce = NONCENSE, 218 .packno = 0xA0A1A2A3A4A5A6A7UL, 219 .bits = GQUIC_PACKNO_LEN_6, 220 .len = 1 + 8 + 32 + 6, 221 .out = { (1 << 2) /* Nonce present */ 222 | 0x08 /* Connection ID present */ 223 | 0x30 /* Packet number length */ 224 , 225 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Connection ID */ 226 NONCENSE_BYTES, 227 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 228 }, 229 }, 230 231 }; 232 233 unsigned i; 234 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) 235 run_test(&tests[i]); 236 return 0; 237} 238