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