test_trapa.c revision 9a690580
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * test_trapa.c -- Test transport parameters. 4 */ 5 6#include <assert.h> 7 8#include <stddef.h> 9#include <stdint.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13#include <unistd.h> 14 15#include "lsquic.h" 16#include "lsquic_types.h" 17#include "lsquic_sizes.h" 18#include "lsquic_logger.h" 19#include "lsquic_trans_params.h" 20 21#define ENC_BUF_SZ 0x1000 22 23struct trapa_test 24{ 25 int line; 26 enum { 27 TEST_ENCODE = 1 << 0, 28 TEST_DECODE = 1 << 1, 29 } flags; 30 struct transport_params params; 31 size_t enc_len, dec_len; 32 unsigned addl_set; 33 int is_server; 34 int expect_decode_err; 35 unsigned char encoded[ENC_BUF_SZ]; 36}; 37 38static const struct trapa_test tests[] = 39{ 40 41 { 42 .line = __LINE__, 43 .flags = TEST_ENCODE | TEST_DECODE, 44 .params = { 45 TP_DEFAULT_VALUES, 46 }, 47 .enc_len = 0, 48 .encoded = 49 /* Trailer to make the end easily visible in gdb: */ 50 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 51 }, 52 53 { 54 .line = __LINE__, 55 .flags = TEST_ENCODE | TEST_DECODE, 56 .params = { 57 .tp_set = (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL) 58 | (1 << TPI_INIT_MAX_DATA) 59 | (1 << TPI_MAX_IDLE_TIMEOUT) 60 | (1 << TPI_MAX_ACK_DELAY) 61 | (1 << TPI_MAX_PACKET_SIZE) 62 | (1 << TPI_ACK_DELAY_EXPONENT) 63 | (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT), 64 .tp_init_max_stream_data_bidi_local = 0x12348877, 65 .tp_init_max_data = 0xAABB, 66 .tp_max_packet_size = 1213, 67 .tp_max_idle_timeout = 10 * 1000, 68 .tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY, 69 .tp_active_connection_id_limit = 7, 70 }, 71 .is_server = 0, 72 .enc_len = 26, 73 .encoded = 74 /* Idle timeout */ "\x01\x02\x67\x10" 75 /* Packet size */ "\x03\x02\x44\xBD" 76 /* Max data */ "\x04\x04\x80\x00\xAA\xBB" 77 /* Bidi local */ "\x05\x04\x92\x34\x88\x77" 78 /* Ack delay exp */ "\x0A\x01\x00" 79 /* Active CID limit */ "\x0E\x01\x07" 80 /* Trailer to make the end easily visible in gdb: */ 81 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 82 }, 83 84 { 85 .line = __LINE__, 86 .flags = TEST_DECODE, 87 .dec_len = 1, 88 .expect_decode_err = 1, 89 }, 90 91 { 92 .line = __LINE__, 93 .flags = TEST_DECODE, 94 .dec_len = 3, 95 .expect_decode_err = 1, 96 .encoded = "\x00\x04", 97 }, 98 99 100 { 101 .line = __LINE__, 102 .flags = TEST_ENCODE | TEST_DECODE, 103 .params = { 104 TP_DEFAULT_VALUES, 105 .tp_init_max_data = 0x123456, 106 .tp_init_max_stream_data_bidi_local = 0xABCDEF88, 107 .tp_max_packet_size = 0x555, 108 }, 109 .is_server = 1, 110 .addl_set = 1 << TPI_DISABLE_ACTIVE_MIGRATION, 111 .enc_len = 22, 112 .encoded = 113 /* Packet size */ "\x03\x02\x45\x55" 114 /* Max data */ "\x04\x04\x80\x12\x34\x56" 115 /* Bidi local */ "\x05\x08\xC0\x00\x00\x00\xAB\xCD\xEF\x88" 116 /* Migration */ "\x0C\x00" 117 /* Trailer to make the end easily visible in gdb: */ 118 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 119 }, 120 121 /* Test server preferred address. */ 122 { 123 .line = __LINE__, 124 .flags = TEST_DECODE, 125 .params = { 126 TP_DEFAULT_VALUES, 127 .tp_max_ack_delay = 25, 128 .tp_max_packet_size = 0x555, 129 .tp_preferred_address = { 130 .ipv4_addr = "\x01\x02\x03\x04", 131 .ipv4_port = 0x1234, 132 .ipv6_addr = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 133 .ipv6_port = 0x9001, 134 .cid = { .len = 11, .idbuf = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A", }, 135 .srst = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F", 136 }, 137 }, 138 .is_server = 1, 139 .addl_set = 1 << TPI_PREFERRED_ADDRESS, 140 .enc_len = 0x3A, 141 .dec_len = 0x3A, 142 .encoded = 143 /* Preferred Address */"\x0D" 144 "\x34" 145 "\x01\x02\x03\x04" 146 "\x12\x34" 147 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" 148 "\x90\x01" 149 "\x0B" /* CID len */ 150 "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A" 151 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" 152 /* Packet size */ "\x03\x02\x45\x55" 153 /* Trailer to make the end easily visible in gdb: */ 154 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 155 }, 156 157}; 158 159 160static int 161params_are_equal (const struct transport_params *a, 162 const struct transport_params *b) 163{ 164#define MCMP(f) 0 == memcmp(&a->f, &b->f, sizeof(a->f)) 165 return MCMP(tp_numerics) 166 && MCMP(tp_set) 167 && MCMP(tp_stateless_reset_token) 168 && MCMP(tp_preferred_address.ipv4_addr) 169 && MCMP(tp_preferred_address.ipv6_addr) 170 && MCMP(tp_preferred_address.srst) 171 && MCMP(tp_preferred_address.cid.idbuf) 172 && a->tp_preferred_address.ipv4_port == b->tp_preferred_address.ipv4_port 173 && a->tp_preferred_address.ipv6_port == b->tp_preferred_address.ipv6_port 174 && a->tp_preferred_address.cid.len == b->tp_preferred_address.cid.len 175 && MCMP(tp_original_cid.idbuf) 176 && a->tp_original_cid.len == b->tp_original_cid.len 177 ; 178#undef MCMP 179} 180 181 182static void 183run_test (const struct trapa_test *test) 184{ 185 struct transport_params source_params; 186 struct transport_params decoded_params; 187 size_t dec_len; 188 int s; 189 unsigned char buf[ENC_BUF_SZ]; 190 191 source_params = test->params; 192 source_params.tp_set |= test->addl_set; 193 194 if (test->flags & TEST_ENCODE) 195 { 196 s = lsquic_tp_encode(&source_params, test->is_server, buf, sizeof(buf)); 197 assert(s >= 0); 198 assert((size_t) s == test->enc_len); 199 assert(0 == memcmp(test->encoded, buf, s)); 200 } 201 202 if (test->flags & TEST_DECODE) 203 { 204 if (test->dec_len) 205 dec_len = test->dec_len; 206 else 207 dec_len = test->enc_len; 208 s = lsquic_tp_decode(test->encoded, dec_len, 209 test->is_server, &decoded_params); 210 if (!test->expect_decode_err) 211 { 212 assert(s >= 0); 213 assert((size_t) s == test->enc_len); 214 /* The decoder initializes all default values, so set the flag 215 * accordingly: 216 */ 217 source_params.tp_set |= ((1 << (MAX_NUM_WITH_DEF_TPI + 1)) - 1); 218 s = params_are_equal(&source_params, &decoded_params); 219 assert(s); 220 } 221 else 222 assert(s < 0); 223 } 224} 225 226 227static void 228decode_file (const char *name) 229{ 230 FILE *file; 231 size_t nread; 232 int s; 233 struct transport_params params; 234 unsigned char buf[0x1000]; 235 236 file = fopen(name, "rb"); 237 if (!file) 238 { 239 perror("fopen"); 240 exit(1); 241 } 242 243 nread = fread(buf, 1, sizeof(buf), file); 244 245 s = lsquic_tp_decode(buf, nread, 0, ¶ms); 246 247 fclose(file); 248 249 printf("decoded params from %s: %d (%s)\n", name, s, s > 0 ? "OK" : "FAIL"); 250} 251 252 253int 254main (int argc, char **argv) 255{ 256 unsigned i; 257 int opt; 258 259 while (-1 != (opt = getopt(argc, argv, "d:l:"))) 260 { 261 switch (opt) 262 { 263 case 'd': 264 decode_file(optarg); 265 return 0; 266 case 'l': 267 lsquic_log_to_fstream(stderr, 0); 268 lsquic_logger_lopt(optarg); 269 break; 270 default: 271 exit(1); 272 } 273 } 274 275 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) 276 run_test(&tests[i]); 277 278 return 0; 279} 280