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