lsquic_trans_params.c revision 77a28812
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_trans_params.c
4 */
5
6#include <assert.h>
7#include <errno.h>
8#include <inttypes.h>
9#include <limits.h>
10#include <stddef.h>
11#include <stdint.h>
12#include <string.h>
13
14#include <arpa/inet.h>
15#include <sys/socket.h>
16
17#include "lsquic_byteswap.h"
18#include "lsquic_int_types.h"
19#include "lsquic_types.h"
20#include "lsquic_version.h"
21#include "lsquic_sizes.h"
22#include "lsquic_trans_params.h"
23#include "lsquic_util.h"
24#include "lsquic_varint.h"
25
26#define LSQUIC_LOGGER_MODULE LSQLM_TRAPA
27#include "lsquic_logger.h"
28
29
30static enum transport_param_id
31tpi_val_2_enum (uint64_t tpi_val)
32{
33    switch (tpi_val)
34    {
35    case 0:         return TPI_ORIGINAL_CONNECTION_ID;
36    case 1:         return TPI_MAX_IDLE_TIMEOUT;
37    case 2:         return TPI_STATELESS_RESET_TOKEN;
38    case 3:         return TPI_MAX_PACKET_SIZE;
39    case 4:         return TPI_INIT_MAX_DATA;
40    case 5:         return TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL;
41    case 6:         return TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE;
42    case 7:         return TPI_INIT_MAX_STREAM_DATA_UNI;
43    case 8:         return TPI_INIT_MAX_STREAMS_BIDI;
44    case 9:         return TPI_INIT_MAX_STREAMS_UNI;
45    case 10:        return TPI_ACK_DELAY_EXPONENT;
46    case 11:        return TPI_MAX_ACK_DELAY;
47    case 12:        return TPI_DISABLE_ACTIVE_MIGRATION;
48    case 13:        return TPI_PREFERRED_ADDRESS;
49    case 14:        return TPI_ACTIVE_CONNECTION_ID_LIMIT;
50#if LSQUIC_TEST_QUANTUM_READINESS
51    case 0xC37:     return TPI_QUANTUM_READINESS;
52#endif
53    case 0x1057:    return TPI_LOSS_BITS;
54    case 0xDE1A:    return TPI_MIN_ACK_DELAY;
55    case 0x7157:    return TPI_TIMESTAMPS;
56    default:        return INT_MAX;
57    }
58}
59
60
61static const unsigned enum_2_tpi_val[LAST_TPI + 1] =
62{
63    [TPI_ORIGINAL_CONNECTION_ID]            =  0x0,
64    [TPI_MAX_IDLE_TIMEOUT]                  =  0x1,
65    [TPI_STATELESS_RESET_TOKEN]             =  0x2,
66    [TPI_MAX_PACKET_SIZE]                   =  0x3,
67    [TPI_INIT_MAX_DATA]                     =  0x4,
68    [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL]   =  0x5,
69    [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE]  =  0x6,
70    [TPI_INIT_MAX_STREAM_DATA_UNI]          =  0x7,
71    [TPI_INIT_MAX_STREAMS_BIDI]             =  0x8,
72    [TPI_INIT_MAX_STREAMS_UNI]              =  0x9,
73    [TPI_ACK_DELAY_EXPONENT]                =  0xA,
74    [TPI_MAX_ACK_DELAY]                     =  0xB,
75    [TPI_DISABLE_ACTIVE_MIGRATION]          =  0xC,
76    [TPI_PREFERRED_ADDRESS]                 =  0xD,
77    [TPI_ACTIVE_CONNECTION_ID_LIMIT]        =  0xE,
78#if LSQUIC_TEST_QUANTUM_READINESS
79    [TPI_QUANTUM_READINESS]                 =  0xC37,
80#endif
81    [TPI_LOSS_BITS]                         =  0x1057,
82    [TPI_MIN_ACK_DELAY]                     =  0xDE1A,
83    [TPI_TIMESTAMPS]                        =  0x7157,
84};
85
86
87static const char * const tpi2str[LAST_TPI + 1] =
88{
89    [TPI_ORIGINAL_CONNECTION_ID]            =  "original_connection_id",
90    [TPI_MAX_IDLE_TIMEOUT]                  =  "max_idle_timeout",
91    [TPI_STATELESS_RESET_TOKEN]             =  "stateless_reset_token",
92    [TPI_MAX_PACKET_SIZE]                   =  "max_packet_size",
93    [TPI_INIT_MAX_DATA]                     =  "init_max_data",
94    [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL]   =  "init_max_stream_data_bidi_local",
95    [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE]  =  "init_max_stream_data_bidi_remote",
96    [TPI_INIT_MAX_STREAM_DATA_UNI]          =  "init_max_stream_data_uni",
97    [TPI_INIT_MAX_STREAMS_BIDI]             =  "init_max_streams_bidi",
98    [TPI_INIT_MAX_STREAMS_UNI]              =  "init_max_streams_uni",
99    [TPI_ACK_DELAY_EXPONENT]                =  "ack_delay_exponent",
100    [TPI_MAX_ACK_DELAY]                     =  "max_ack_delay",
101    [TPI_DISABLE_ACTIVE_MIGRATION]          =  "disable_active_migration",
102    [TPI_PREFERRED_ADDRESS]                 =  "preferred_address",
103    [TPI_ACTIVE_CONNECTION_ID_LIMIT]        =  "active_connection_id_limit",
104#if LSQUIC_TEST_QUANTUM_READINESS
105    [TPI_QUANTUM_READINESS]                 =  "quantum_readiness",
106#endif
107    [TPI_LOSS_BITS]                         =  "loss_bits",
108    [TPI_MIN_ACK_DELAY]                     =  "min_ack_delay",
109    [TPI_TIMESTAMPS]                        =  "timestamps",
110};
111
112
113static const uint64_t def_vals[MAX_NUM_WITH_DEF_TPI + 1] =
114{
115    [TPI_MAX_PACKET_SIZE]                   =  TP_DEF_MAX_PACKET_SIZE,
116    [TPI_ACK_DELAY_EXPONENT]                =  TP_DEF_ACK_DELAY_EXP,
117    [TPI_INIT_MAX_STREAMS_UNI]              =  TP_DEF_INIT_MAX_STREAMS_UNI,
118    [TPI_INIT_MAX_STREAMS_BIDI]             =  TP_DEF_INIT_MAX_STREAMS_BIDI,
119    [TPI_INIT_MAX_DATA]                     =  TP_DEF_INIT_MAX_DATA,
120    [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL]   =  TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL,
121    [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE]  =  TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE,
122    [TPI_INIT_MAX_STREAM_DATA_UNI]          =  TP_DEF_INIT_MAX_STREAM_DATA_UNI,
123    [TPI_MAX_IDLE_TIMEOUT]                  =  TP_DEF_MAX_IDLE_TIMEOUT,
124    [TPI_MAX_ACK_DELAY]                     =  TP_DEF_MAX_ACK_DELAY,
125    [TPI_ACTIVE_CONNECTION_ID_LIMIT]        =  TP_DEF_ACTIVE_CONNECTION_ID_LIMIT,
126};
127
128
129static const uint64_t max_vals[MAX_NUMERIC_TPI + 1] =
130{
131    /* We don't enforce the maximum practical UDP payload value of 65527, as
132     * it is not required by the spec and is not necessary.
133     */
134    [TPI_MAX_PACKET_SIZE]                   =  VINT_MAX_VALUE,
135    [TPI_ACK_DELAY_EXPONENT]                =  VINT_MAX_VALUE,
136    [TPI_INIT_MAX_STREAMS_UNI]              =  VINT_MAX_VALUE,
137    [TPI_INIT_MAX_STREAMS_BIDI]             =  VINT_MAX_VALUE,
138    [TPI_INIT_MAX_DATA]                     =  VINT_MAX_VALUE,
139    [TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL]   =  VINT_MAX_VALUE,
140    [TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE]  =  VINT_MAX_VALUE,
141    [TPI_INIT_MAX_STREAM_DATA_UNI]          =  VINT_MAX_VALUE,
142    [TPI_MAX_IDLE_TIMEOUT]                  =  VINT_MAX_VALUE,
143    [TPI_MAX_ACK_DELAY]                     =  TP_MAX_MAX_ACK_DELAY,
144    [TPI_ACTIVE_CONNECTION_ID_LIMIT]        =  VINT_MAX_VALUE,
145    [TPI_LOSS_BITS]                         =  1,
146    [TPI_MIN_ACK_DELAY]                     =  (1u << 24) - 1u,
147};
148
149
150static const uint64_t min_vals[MAX_NUMERIC_TPI + 1] =
151{
152    /* On the other hand, we do enforce the lower bound. */
153    [TPI_MAX_PACKET_SIZE]                   =  1200,
154    [TPI_MIN_ACK_DELAY]                     =  1,
155};
156
157
158static size_t
159preferred_address_size (const struct transport_params *params)
160{
161    return sizeof(params->tp_preferred_address.ipv4_addr)
162         + sizeof(params->tp_preferred_address.ipv4_port)
163         + sizeof(params->tp_preferred_address.ipv6_addr)
164         + sizeof(params->tp_preferred_address.ipv6_port)
165         + 1 + params->tp_preferred_address.cid.len
166         + sizeof(params->tp_preferred_address.srst)
167         ;
168}
169
170
171int
172lsquic_tp_has_pref_ipv4 (const struct transport_params *params)
173{
174    return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS))
175        && params->tp_preferred_address.ipv4_port
176        && !lsquic_is_zero(params->tp_preferred_address.ipv4_addr,
177                    sizeof(params->tp_preferred_address.ipv4_addr));
178}
179
180
181int
182lsquic_tp_has_pref_ipv6 (const struct transport_params *params)
183{
184    return (params->tp_set & (1 << TPI_PREFERRED_ADDRESS))
185        && params->tp_preferred_address.ipv6_port
186        && !lsquic_is_zero(params->tp_preferred_address.ipv6_addr,
187                    sizeof(params->tp_preferred_address.ipv6_addr));
188}
189
190
191int
192lsquic_tp_encode (const struct transport_params *params, int is_server,
193                  unsigned char *const buf, size_t bufsz)
194{
195    unsigned char *p;
196    size_t need;
197    uint16_t u16;
198    enum transport_param_id tpi;
199    unsigned set;
200    unsigned bits[LAST_TPI + 1][3 /* ID, length, value */];
201
202    need = 0;
203    set = params->tp_set;   /* Will turn bits off for default values */
204
205    if (is_server)
206    {
207        if (set & (1 << TPI_ORIGINAL_CONNECTION_ID))
208        {
209            bits[TPI_ORIGINAL_CONNECTION_ID][0]
210                    = vint_val2bits(enum_2_tpi_val[TPI_ORIGINAL_CONNECTION_ID]);
211#if __GNUC__
212#pragma GCC diagnostic ignored "-Wunknown-pragmas"
213#if __clang__
214#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
215#else
216#pragma GCC diagnostic ignored "-Wtype-limits"
217#endif
218#endif
219            bits[TPI_ORIGINAL_CONNECTION_ID][1]
220                    = vint_val2bits(params->tp_original_cid.len);
221#if __GNUC__
222#pragma GCC diagnostic pop
223#pragma GCC diagnostic pop
224#endif
225            need += (1 << bits[TPI_ORIGINAL_CONNECTION_ID][0])
226                 +  (1 << bits[TPI_ORIGINAL_CONNECTION_ID][1])
227                 +  params->tp_original_cid.len;
228        }
229        if (set & (1 << TPI_STATELESS_RESET_TOKEN))
230        {
231            bits[TPI_STATELESS_RESET_TOKEN][0]
232                    = vint_val2bits(enum_2_tpi_val[TPI_STATELESS_RESET_TOKEN]);
233            bits[TPI_STATELESS_RESET_TOKEN][1]
234                    = vint_val2bits(sizeof(params->tp_stateless_reset_token));
235            need += (1 << bits[TPI_STATELESS_RESET_TOKEN][0])
236                 +  (1 << bits[TPI_STATELESS_RESET_TOKEN][1])
237                 +  sizeof(params->tp_stateless_reset_token);
238        }
239        if (set & (1 << TPI_PREFERRED_ADDRESS))
240        {
241            bits[TPI_PREFERRED_ADDRESS][0]
242                    = vint_val2bits(enum_2_tpi_val[TPI_PREFERRED_ADDRESS]);
243            bits[TPI_PREFERRED_ADDRESS][1] = vint_val2bits(
244                                            preferred_address_size(params));
245            need += (1 << bits[TPI_PREFERRED_ADDRESS][0])
246                 +  (1 << bits[TPI_PREFERRED_ADDRESS][1])
247                 +  preferred_address_size(params);
248        }
249    }
250#if LSQUIC_TEST_QUANTUM_READINESS
251    else if (set & (1 << TPI_QUANTUM_READINESS))
252    {
253        bits[TPI_QUANTUM_READINESS][0]
254                = vint_val2bits(enum_2_tpi_val[TPI_QUANTUM_READINESS]);
255        bits[TPI_QUANTUM_READINESS][1] = vint_val2bits(QUANTUM_READY_SZ);
256        need += (1 << bits[TPI_QUANTUM_READINESS][0])
257             +  (1 << bits[TPI_QUANTUM_READINESS][1])
258             +  QUANTUM_READY_SZ;
259    }
260#endif
261
262    for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
263        if (set & (1 << tpi))
264        {
265            if (tpi > MAX_NUM_WITH_DEF_TPI
266                        || params->tp_numerics[tpi] != def_vals[tpi])
267            {
268                if (params->tp_numerics[tpi] >= min_vals[tpi]
269                                && params->tp_numerics[tpi] <= max_vals[tpi])
270                {
271                    bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]);
272                    bits[tpi][2] = vint_val2bits(params->tp_numerics[tpi]);
273                    bits[tpi][1] = vint_val2bits(bits[tpi][2]);
274                    need += (1 << bits[tpi][0])
275                         +  (1 << bits[tpi][1])
276                         +  (1 << bits[tpi][2]);
277                }
278                else if (params->tp_numerics[tpi] > max_vals[tpi])
279                {
280                    LSQ_DEBUG("numeric value of %s is too large (%"PRIu64" vs "
281                        "maximum of %"PRIu64")", tpi2str[tpi],
282                        params->tp_numerics[tpi], max_vals[tpi]);
283                    return -1;
284                }
285                else
286                {
287                    LSQ_DEBUG("numeric value of %s is too small (%"PRIu64" vs "
288                        "minimum " "of %"PRIu64")",
289                        tpi2str[tpi], params->tp_numerics[tpi], min_vals[tpi]);
290                    return -1;
291                }
292            }
293            else
294                set &= ~(1 << tpi);     /* Don't write default value */
295        }
296
297    for (; tpi <= MAX_EMPTY_TPI; ++tpi)
298        if (set & (1 << tpi))
299        {
300            bits[tpi][0] = vint_val2bits(enum_2_tpi_val[tpi]);
301            need += (1 << bits[tpi][0]) + 1 /* Zero length byte */;
302        }
303
304    if (need > bufsz || need > UINT16_MAX)
305    {
306        errno = ENOBUFS;
307        return -1;
308    }
309
310    p = buf;
311
312#define WRITE_TO_P(src, len) do {                                       \
313    memcpy(p, src, len);                                                \
314    p += len;                                                           \
315} while (0)
316
317#if __BYTE_ORDER == __LITTLE_ENDIAN
318#define WRITE_UINT_TO_P(val, width) do {                                \
319    u##width = bswap_##width(val);                                      \
320    WRITE_TO_P(&u##width, sizeof(u##width));                            \
321} while (0)
322#else
323#define WRITE_UINT_TO_P(val, width) do {                                \
324    u##width = val;                                                     \
325    WRITE_TO_P(&u##width, sizeof(u##width));                            \
326} while (0)
327#endif
328
329    for (tpi = 0; tpi <= LAST_TPI; ++tpi)
330        if (set & (1 << tpi))
331        {
332            vint_write(p, enum_2_tpi_val[tpi], bits[tpi][0],
333                                                        1 << bits[tpi][0]);
334            p += 1 << bits[tpi][0];
335            switch (tpi)
336            {
337            case TPI_MAX_IDLE_TIMEOUT:
338            case TPI_MAX_PACKET_SIZE:
339            case TPI_INIT_MAX_DATA:
340            case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL:
341            case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE:
342            case TPI_INIT_MAX_STREAM_DATA_UNI:
343            case TPI_INIT_MAX_STREAMS_BIDI:
344            case TPI_INIT_MAX_STREAMS_UNI:
345            case TPI_ACK_DELAY_EXPONENT:
346            case TPI_MAX_ACK_DELAY:
347            case TPI_ACTIVE_CONNECTION_ID_LIMIT:
348            case TPI_LOSS_BITS:
349            case TPI_MIN_ACK_DELAY:
350                vint_write(p, 1 << bits[tpi][2], bits[tpi][1],
351                                                            1 << bits[tpi][1]);
352                p += 1 << bits[tpi][1];
353                vint_write(p, params->tp_numerics[tpi], bits[tpi][2],
354                                                            1 << bits[tpi][2]);
355                p += 1 << bits[tpi][2];
356                break;
357            case TPI_ORIGINAL_CONNECTION_ID:
358                vint_write(p, params->tp_original_cid.len, bits[tpi][1],
359                                                            1 << bits[tpi][1]);
360                p += 1 << bits[tpi][1];
361                WRITE_TO_P(params->tp_original_cid.idbuf,
362                                            params->tp_original_cid.len);
363                break;
364            case TPI_STATELESS_RESET_TOKEN:
365                vint_write(p, sizeof(params->tp_stateless_reset_token),
366                                            bits[tpi][1], 1 << bits[tpi][1]);
367                p += 1 << bits[tpi][1];
368                WRITE_TO_P(params->tp_stateless_reset_token,
369                                sizeof(params->tp_stateless_reset_token));
370                break;
371            case TPI_PREFERRED_ADDRESS:
372                vint_write(p, preferred_address_size(params),
373                                            bits[tpi][1], 1 << bits[tpi][1]);
374                p += 1 << bits[tpi][1];
375                WRITE_UINT_TO_P(preferred_address_size(params), 16);
376                WRITE_TO_P(&params->tp_preferred_address.ipv4_addr,
377                        sizeof(params->tp_preferred_address.ipv4_addr));
378                WRITE_UINT_TO_P(params->tp_preferred_address.ipv4_port, 16);
379                WRITE_TO_P(&params->tp_preferred_address.ipv6_addr,
380                        sizeof(params->tp_preferred_address.ipv6_addr));
381                WRITE_UINT_TO_P(params->tp_preferred_address.ipv6_port, 16);
382                *p++ = params->tp_preferred_address.cid.len;
383                WRITE_TO_P(params->tp_preferred_address.cid.idbuf,
384                                    params->tp_preferred_address.cid.len);
385                WRITE_TO_P(params->tp_preferred_address.srst,
386                                sizeof(params->tp_preferred_address.srst));
387                break;
388            case TPI_DISABLE_ACTIVE_MIGRATION:
389            case TPI_TIMESTAMPS:
390                *p++ = 0;
391                break;
392#if LSQUIC_TEST_QUANTUM_READINESS
393            case TPI_QUANTUM_READINESS:
394                vint_write(p, QUANTUM_READY_SZ,
395                                            bits[tpi][1], 1 << bits[tpi][1]);
396                p += 1 << bits[tpi][1];
397                memset(p, 'Q', QUANTUM_READY_SZ);
398                p += QUANTUM_READY_SZ;
399                break;
400#endif
401            }
402        }
403
404    assert(buf + need == p);
405    return (int) (p - buf);
406
407#undef WRITE_TO_P
408#undef WRITE_UINT_TO_P
409}
410
411
412int
413lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
414                  int is_server,
415                  struct transport_params *params)
416{
417    const unsigned char *p, *end, *q;
418    uint64_t len, param_id;
419    uint16_t tlen;
420    enum transport_param_id tpi;
421    unsigned set_of_ids;
422    int s;
423
424    p = buf;
425    end = buf + bufsz;
426
427    *params = TP_INITIALIZER();
428
429#define EXPECT_LEN(expected_len) do {                               \
430    if (expected_len != len)                                        \
431        return -1;                                                  \
432} while (0)
433
434#define EXPECT_AT_LEAST(expected_len) do {                          \
435    if ((expected_len) > (uintptr_t) (p + len - q))                 \
436        return -1;                                                  \
437} while (0)
438
439    set_of_ids = 0;
440    while (p < end)
441    {
442        s = vint_read(p, end, &param_id);
443        if (s < 0)
444            return -1;
445        p += s;
446        s = vint_read(p, end, &len);
447        if (s < 0)
448            return -1;
449        p += s;
450        if ((ptrdiff_t) len > end - p)
451            return -1;
452        tpi = tpi_val_2_enum(param_id);
453        if (tpi <= LAST_TPI)
454        {
455            if (set_of_ids & (1 << tpi))
456                return -1;
457            set_of_ids |= 1 << tpi;
458        }
459        switch (tpi)
460        {
461        case TPI_MAX_IDLE_TIMEOUT:
462        case TPI_MAX_PACKET_SIZE:
463        case TPI_INIT_MAX_DATA:
464        case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL:
465        case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE:
466        case TPI_INIT_MAX_STREAM_DATA_UNI:
467        case TPI_INIT_MAX_STREAMS_BIDI:
468        case TPI_INIT_MAX_STREAMS_UNI:
469        case TPI_ACK_DELAY_EXPONENT:
470        case TPI_MAX_ACK_DELAY:
471        case TPI_ACTIVE_CONNECTION_ID_LIMIT:
472        case TPI_LOSS_BITS:
473        case TPI_MIN_ACK_DELAY:
474            switch (len)
475            {
476            case 1:
477            case 2:
478            case 4:
479            case 8:
480                s = vint_read(p, p + len, &params->tp_numerics[tpi]);
481                if (s == (int) len)
482                {
483                    if (params->tp_numerics[tpi] > max_vals[tpi])
484                    {
485                        LSQ_DEBUG("numeric value of %s is too large "
486                            "(%"PRIu64" vs maximum of %"PRIu64, tpi2str[tpi],
487                            params->tp_numerics[tpi], max_vals[tpi]);
488                        return -1;
489                    }
490                    else if (params->tp_numerics[tpi] < min_vals[tpi])
491                    {
492                        LSQ_DEBUG("numeric value of %s is too small "
493                            "(%"PRIu64" vs minimum of %"PRIu64, tpi2str[tpi],
494                            params->tp_numerics[tpi], min_vals[tpi]);
495                        return -1;
496                    }
497                    break;
498                }
499                else
500                {
501                    LSQ_DEBUG("cannot read the value of numeric transport "
502                            "param %s of length %"PRIu64, tpi2str[tpi], len);
503                    return -1;
504                }
505            default:
506                LSQ_DEBUG("invalid length=%"PRIu64" for numeric transport "
507                                            "parameter %s", len, tpi2str[tpi]);
508                return -1;
509            }
510            break;
511        case TPI_DISABLE_ACTIVE_MIGRATION:
512        case TPI_TIMESTAMPS:
513            EXPECT_LEN(0);
514            break;
515        case TPI_STATELESS_RESET_TOKEN:
516            /* Client MUST not include reset token,
517             * see [draft-ietf-quic-transport-11], Section 6.4.1
518             */
519            if (!is_server)
520                return -1;
521            EXPECT_LEN(sizeof(params->tp_stateless_reset_token));
522            memcpy(params->tp_stateless_reset_token, p,
523                                sizeof(params->tp_stateless_reset_token));
524            break;
525        case TPI_ORIGINAL_CONNECTION_ID:
526            /* Client MUST not original connecti ID,
527             * see [draft-ietf-quic-transport-15], Section 6.6.1
528             */
529            if (!is_server)
530                return -1;
531            if (len > MAX_CID_LEN)
532                return -1;
533            memcpy(params->tp_original_cid.idbuf, p, len);
534            params->tp_original_cid.len = len;
535            break;
536        case TPI_PREFERRED_ADDRESS:
537            /* Client MUST not include preferred address,
538             * see [draft-ietf-quic-transport-12], Section 6.4.1
539             */
540            if (!is_server)
541                return -1;
542            q = p;
543            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_addr));
544            memcpy(params->tp_preferred_address.ipv4_addr, q,
545                        sizeof(params->tp_preferred_address.ipv4_addr));
546            q += sizeof(params->tp_preferred_address.ipv4_addr);
547            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_port));
548            READ_UINT(params->tp_preferred_address.ipv4_port, 16, q, 2);
549            q += 2;
550            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_addr));
551            memcpy(params->tp_preferred_address.ipv6_addr, q,
552                        sizeof(params->tp_preferred_address.ipv6_addr));
553            q += sizeof(params->tp_preferred_address.ipv6_addr);
554            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_port));
555            READ_UINT(params->tp_preferred_address.ipv6_port, 16, q, 2);
556            q += 2;
557            EXPECT_AT_LEAST(1);
558            tlen = *q;
559            q += 1;
560            if (tlen < 4 || tlen > MAX_CID_LEN)
561            {
562                LSQ_DEBUG("preferred server address contains invalid "
563                    "CID length of %"PRIu16" bytes", tlen);
564                return -1;
565            }
566            EXPECT_AT_LEAST(tlen);
567            memcpy(params->tp_preferred_address.cid.idbuf, q, tlen);
568            params->tp_preferred_address.cid.len = tlen;
569            q += tlen;
570            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.srst));
571            memcpy(params->tp_preferred_address.srst, q,
572                            sizeof(params->tp_preferred_address.srst));
573            q += sizeof(params->tp_preferred_address.srst);
574            if (q != p + len)
575                return -1;
576            break;
577        default:
578            /* Do nothing: skip this transport parameter */
579            break;
580        }
581        p += len;
582        if (tpi <= LAST_TPI)
583        {
584            params->tp_set |= 1 << tpi;
585            params->tp_decoded |= 1 << tpi;
586        }
587    }
588
589    if (p != end)
590        return -1;
591
592    if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY))
593            && params->tp_numerics[TPI_MIN_ACK_DELAY]
594                            > params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000)
595    {
596        LSQ_DEBUG("min_ack_delay (%"PRIu64" usec) is larger than "
597            "max_ack_delay (%"PRIu64" ms)",
598            params->tp_numerics[TPI_MIN_ACK_DELAY],
599            params->tp_numerics[TPI_MAX_ACK_DELAY]);
600        return -1;
601    }
602
603    return (int) (end - buf);
604#undef EXPECT_LEN
605}
606
607
608void
609lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz)
610{
611    char *const end = buf + sz;
612    int nw;
613    enum transport_param_id tpi;
614    char tok_str[sizeof(params->tp_stateless_reset_token) * 2 + 1];
615    char addr_str[INET6_ADDRSTRLEN];
616
617    for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
618        if (params->tp_set & (1 << tpi))
619        {
620            nw = snprintf(buf, end - buf, "%.*s%s: %"PRIu64,
621                (buf + sz > end) << 1, "; ", tpi2str[tpi],
622                params->tp_numerics[tpi]);
623            buf += nw;
624            if (buf >= end)
625                return;
626        }
627    for (; tpi <= MAX_EMPTY_TPI; ++tpi)
628        if (params->tp_set & (1 << tpi))
629        {
630            nw = snprintf(buf, end - buf, "%.*s%s",
631                                    (buf + sz > end) << 1, "; ", tpi2str[tpi]);
632            buf += nw;
633            if (buf >= end)
634                return;
635        }
636#if LSQUIC_TEST_QUANTUM_READINESS
637    if (params->tp_set & (1 << TPI_QUANTUM_READINESS))
638    {
639        nw = snprintf(buf, end - buf, "%.*s%s",
640                (buf + sz > end) << 1, "; ", tpi2str[TPI_QUANTUM_READINESS]);
641        buf += nw;
642        if (buf >= end)
643            return;
644    }
645#endif
646    if (params->tp_set & (1 << TPI_STATELESS_RESET_TOKEN))
647    {
648        lsquic_hexstr(params->tp_stateless_reset_token,
649            sizeof(params->tp_stateless_reset_token), tok_str, sizeof(tok_str));
650        nw = snprintf(buf, end - buf, "; stateless_reset_token: %s", tok_str);
651        buf += nw;
652        if (buf >= end)
653            return;
654    }
655    if (params->tp_set & (1 << TPI_ORIGINAL_CONNECTION_ID))
656    {
657        char cidbuf_[MAX_CID_LEN * 2 + 1];
658        nw = snprintf(buf, end - buf, "; original DCID (ODCID): %"CID_FMT,
659                                        CID_BITS(&params->tp_original_cid));
660        buf += nw;
661        if (buf >= end)
662            return;
663    }
664    if (lsquic_tp_has_pref_ipv4(params))
665    {
666        if (inet_ntop(AF_INET, params->tp_preferred_address.ipv4_addr,
667                                                addr_str, sizeof(addr_str)))
668        {
669            nw = snprintf(buf, end - buf, "; IPv4 preferred address: %s:%u",
670                            addr_str, params->tp_preferred_address.ipv4_port);
671            buf += nw;
672            if (buf >= end)
673                return;
674        }
675    }
676    if (lsquic_tp_has_pref_ipv6(params))
677    {
678        if (inet_ntop(AF_INET6, params->tp_preferred_address.ipv6_addr,
679                                                addr_str, sizeof(addr_str)))
680        {
681            nw = snprintf(buf, end - buf, "; IPv6 preferred address: %s:%u",
682                            addr_str, params->tp_preferred_address.ipv6_port);
683            buf += nw;
684            if (buf >= end)
685                return;
686        }
687    }
688}
689
690
691int
692lsquic_tp_encode_id25 (const struct transport_params *params, int is_server,
693                  unsigned char *const buf, size_t bufsz)
694{
695    unsigned char *p;
696    size_t need = 2;
697    uint16_t u16;
698    enum transport_param_id tpi;
699    unsigned set;
700    unsigned bits[MAX_NUMERIC_TPI + 1];
701
702    set = params->tp_set;   /* Will turn bits off for default values */
703
704    if (is_server)
705    {
706        if (set & (1 << TPI_ORIGINAL_CONNECTION_ID))
707            need += 4 + params->tp_original_cid.len;
708        if (set & (1 << TPI_STATELESS_RESET_TOKEN))
709            need += 4 + sizeof(params->tp_stateless_reset_token);
710        if (set & (1 << TPI_PREFERRED_ADDRESS))
711            need += 4 + preferred_address_size(params);
712    }
713#if LSQUIC_TEST_QUANTUM_READINESS
714    else if (set & (1 << TPI_QUANTUM_READINESS))
715        need += 4 + QUANTUM_READY_SZ;
716#endif
717
718    for (tpi = 0; tpi <= MAX_NUMERIC_TPI; ++tpi)
719        if (set & (1 << tpi))
720        {
721            if (tpi > MAX_NUM_WITH_DEF_TPI
722                        || params->tp_numerics[tpi] != def_vals[tpi])
723            {
724                if (params->tp_numerics[tpi] >= min_vals[tpi]
725                                && params->tp_numerics[tpi] <= max_vals[tpi])
726                {
727                    bits[tpi] = vint_val2bits(params->tp_numerics[tpi]);
728                    need += 4 + (1 << bits[tpi]);
729                }
730                else if (params->tp_numerics[tpi] > max_vals[tpi])
731                {
732                    LSQ_DEBUG("numeric value of %s is too large (%"PRIu64" vs "
733                        "maximum of %"PRIu64")", tpi2str[tpi],
734                        params->tp_numerics[tpi], max_vals[tpi]);
735                    return -1;
736                }
737                else
738                {
739                    LSQ_DEBUG("numeric value of %s is too small (%"PRIu64" vs "
740                        "minimum " "of %"PRIu64")",
741                        tpi2str[tpi], params->tp_numerics[tpi], min_vals[tpi]);
742                    return -1;
743                }
744            }
745            else
746                set &= ~(1 << tpi);     /* Don't write default value */
747        }
748
749    for (; tpi <= MAX_EMPTY_TPI; ++tpi)
750        if (set & (1 << tpi))
751            need += 4 + 0;
752
753    if (need > bufsz || need > UINT16_MAX)
754    {
755        errno = ENOBUFS;
756        return -1;
757    }
758
759    p = buf;
760
761#define WRITE_TO_P(src, len) do {                                       \
762    memcpy(p, src, len);                                                \
763    p += len;                                                           \
764} while (0)
765
766#if __BYTE_ORDER == __LITTLE_ENDIAN
767#define WRITE_UINT_TO_P(val, width) do {                                \
768    u##width = bswap_##width(val);                                      \
769    WRITE_TO_P(&u##width, sizeof(u##width));                            \
770} while (0)
771#else
772#define WRITE_UINT_TO_P(val, width) do {                                \
773    u##width = val;                                                     \
774    WRITE_TO_P(&u##width, sizeof(u##width));                            \
775} while (0)
776#endif
777
778#define WRITE_PARAM_TO_P(tpidx, tpval, width) do {                      \
779    WRITE_UINT_TO_P(tpidx, 16);                                         \
780    WRITE_UINT_TO_P(width / 8, 16);                                     \
781    if (width > 8)                                                      \
782        WRITE_UINT_TO_P(tpval, width);                                  \
783    else if (width)                                                     \
784        *p++ = tpval;                                                   \
785} while (0)
786
787    WRITE_UINT_TO_P(need - 2 + buf - p, 16);
788
789    for (tpi = 0; tpi <= LAST_TPI; ++tpi)
790        if (set & (1 << tpi))
791        {
792            WRITE_UINT_TO_P(enum_2_tpi_val[tpi], 16);
793            switch (tpi)
794            {
795            case TPI_MAX_IDLE_TIMEOUT:
796            case TPI_MAX_PACKET_SIZE:
797            case TPI_INIT_MAX_DATA:
798            case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL:
799            case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE:
800            case TPI_INIT_MAX_STREAM_DATA_UNI:
801            case TPI_INIT_MAX_STREAMS_BIDI:
802            case TPI_INIT_MAX_STREAMS_UNI:
803            case TPI_ACK_DELAY_EXPONENT:
804            case TPI_MAX_ACK_DELAY:
805            case TPI_ACTIVE_CONNECTION_ID_LIMIT:
806            case TPI_LOSS_BITS:
807            case TPI_MIN_ACK_DELAY:
808                WRITE_UINT_TO_P(1 << bits[tpi], 16);
809                vint_write(p, params->tp_numerics[tpi], bits[tpi],
810                                                                1 << bits[tpi]);
811                p += 1 << bits[tpi];
812                break;
813            case TPI_ORIGINAL_CONNECTION_ID:
814                WRITE_UINT_TO_P(params->tp_original_cid.len, 16);
815                WRITE_TO_P(params->tp_original_cid.idbuf,
816                                            params->tp_original_cid.len);
817                break;
818            case TPI_STATELESS_RESET_TOKEN:
819                WRITE_UINT_TO_P(sizeof(params->tp_stateless_reset_token), 16);
820                WRITE_TO_P(params->tp_stateless_reset_token,
821                                sizeof(params->tp_stateless_reset_token));
822                break;
823            case TPI_PREFERRED_ADDRESS:
824                WRITE_UINT_TO_P(preferred_address_size(params), 16);
825                WRITE_TO_P(&params->tp_preferred_address.ipv4_addr,
826                        sizeof(params->tp_preferred_address.ipv4_addr));
827                WRITE_UINT_TO_P(params->tp_preferred_address.ipv4_port, 16);
828                WRITE_TO_P(&params->tp_preferred_address.ipv6_addr,
829                        sizeof(params->tp_preferred_address.ipv6_addr));
830                WRITE_UINT_TO_P(params->tp_preferred_address.ipv6_port, 16);
831                *p++ = params->tp_preferred_address.cid.len;
832                WRITE_TO_P(params->tp_preferred_address.cid.idbuf,
833                                    params->tp_preferred_address.cid.len);
834                WRITE_TO_P(params->tp_preferred_address.srst,
835                                sizeof(params->tp_preferred_address.srst));
836                break;
837            case TPI_DISABLE_ACTIVE_MIGRATION:
838            case TPI_TIMESTAMPS:
839                WRITE_UINT_TO_P(0, 16);
840                break;
841#if LSQUIC_TEST_QUANTUM_READINESS
842            case TPI_QUANTUM_READINESS:
843                WRITE_UINT_TO_P(QUANTUM_READY_SZ, 16);
844                memset(p, 'Q', QUANTUM_READY_SZ);
845                p += QUANTUM_READY_SZ;
846                break;
847#endif
848            }
849        }
850
851    assert(buf + need == p);
852    return (int) (p - buf);
853
854#undef WRITE_TO_P
855#undef WRITE_UINT_TO_P
856}
857
858
859int
860lsquic_tp_decode_id25 (const unsigned char *const buf, size_t bufsz,
861                  int is_server,
862                  struct transport_params *params)
863{
864    const unsigned char *p, *end, *q;
865    uint16_t len, param_id, tlen;
866    enum transport_param_id tpi;
867    unsigned set_of_ids;
868    int s;
869
870    p = buf;
871    end = buf + bufsz;
872
873    *params = TP_INITIALIZER();
874
875    if (end - p < 2)
876        return -1;
877    READ_UINT(len, 16, p, 2);
878    p += 2;
879    if (len > end - p)
880        return -1;
881    end = p + len;
882
883#define EXPECT_LEN(expected_len) do {                               \
884    if (expected_len != len)                                        \
885        return -1;                                                  \
886} while (0)
887
888#define EXPECT_AT_LEAST(expected_len) do {                          \
889    if ((expected_len) > (uintptr_t) (p + len - q))                 \
890        return -1;                                                  \
891} while (0)
892
893    set_of_ids = 0;
894    while (p + 4 <= end)
895    {
896        READ_UINT(param_id, 16, p, 2);
897        p += 2;
898        READ_UINT(len, 16, p, 2);
899        p += 2;
900        if (len > end - p)
901            return -1;
902        tpi = tpi_val_2_enum(param_id);
903        if (tpi <= LAST_TPI)
904        {
905            if (set_of_ids & (1 << tpi))
906                return -1;
907            set_of_ids |= 1 << tpi;
908        }
909        switch (tpi)
910        {
911        case TPI_MAX_IDLE_TIMEOUT:
912        case TPI_MAX_PACKET_SIZE:
913        case TPI_INIT_MAX_DATA:
914        case TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL:
915        case TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE:
916        case TPI_INIT_MAX_STREAM_DATA_UNI:
917        case TPI_INIT_MAX_STREAMS_BIDI:
918        case TPI_INIT_MAX_STREAMS_UNI:
919        case TPI_ACK_DELAY_EXPONENT:
920        case TPI_MAX_ACK_DELAY:
921        case TPI_ACTIVE_CONNECTION_ID_LIMIT:
922        case TPI_LOSS_BITS:
923        case TPI_MIN_ACK_DELAY:
924            switch (len)
925            {
926            case 1:
927            case 2:
928            case 4:
929            case 8:
930                s = vint_read(p, p + len, &params->tp_numerics[tpi]);
931                if (s == len)
932                {
933                    if (params->tp_numerics[tpi] > max_vals[tpi])
934                    {
935                        LSQ_DEBUG("numeric value of %s is too large "
936                            "(%"PRIu64" vs maximum of %"PRIu64, tpi2str[tpi],
937                            params->tp_numerics[tpi], max_vals[tpi]);
938                        return -1;
939                    }
940                    else if (params->tp_numerics[tpi] < min_vals[tpi])
941                    {
942                        LSQ_DEBUG("numeric value of %s is too small "
943                            "(%"PRIu64" vs minimum of %"PRIu64, tpi2str[tpi],
944                            params->tp_numerics[tpi], min_vals[tpi]);
945                        return -1;
946                    }
947                    break;
948                }
949                else
950                {
951                    LSQ_DEBUG("cannot read the value of numeric transport "
952                                        "param %u of length %u", param_id, len);
953                    return -1;
954                }
955            default:
956                LSQ_DEBUG("invalid length=%u for numeric transport "
957                                            "parameter 0x%X", len, param_id);
958                return -1;
959            }
960            break;
961        case TPI_DISABLE_ACTIVE_MIGRATION:
962        case TPI_TIMESTAMPS:
963            EXPECT_LEN(0);
964            break;
965        case TPI_STATELESS_RESET_TOKEN:
966            /* Client MUST not include reset token,
967             * see [draft-ietf-quic-transport-11], Section 6.4.1
968             */
969            if (!is_server)
970                return -1;
971            EXPECT_LEN(sizeof(params->tp_stateless_reset_token));
972            memcpy(params->tp_stateless_reset_token, p,
973                                sizeof(params->tp_stateless_reset_token));
974            break;
975        case TPI_ORIGINAL_CONNECTION_ID:
976            /* Client MUST not original connecti ID,
977             * see [draft-ietf-quic-transport-15], Section 6.6.1
978             */
979            if (!is_server)
980                return -1;
981            if (len > MAX_CID_LEN)
982                return -1;
983            memcpy(params->tp_original_cid.idbuf, p, len);
984            params->tp_original_cid.len = len;
985            break;
986        case TPI_PREFERRED_ADDRESS:
987            /* Client MUST not include preferred address,
988             * see [draft-ietf-quic-transport-12], Section 6.4.1
989             */
990            if (!is_server)
991                return -1;
992            q = p;
993            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_addr));
994            memcpy(params->tp_preferred_address.ipv4_addr, q,
995                        sizeof(params->tp_preferred_address.ipv4_addr));
996            q += sizeof(params->tp_preferred_address.ipv4_addr);
997            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv4_port));
998            READ_UINT(params->tp_preferred_address.ipv4_port, 16, q, 2);
999            q += 2;
1000            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_addr));
1001            memcpy(params->tp_preferred_address.ipv6_addr, q,
1002                        sizeof(params->tp_preferred_address.ipv6_addr));
1003            q += sizeof(params->tp_preferred_address.ipv6_addr);
1004            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.ipv6_port));
1005            READ_UINT(params->tp_preferred_address.ipv6_port, 16, q, 2);
1006            q += 2;
1007            EXPECT_AT_LEAST(1);
1008            tlen = *q;
1009            q += 1;
1010            if (tlen < 4 || tlen > MAX_CID_LEN)
1011            {
1012                LSQ_DEBUG("preferred server address contains invalid "
1013                    "CID length of %"PRIu16" bytes", tlen);
1014                return -1;
1015            }
1016            EXPECT_AT_LEAST(tlen);
1017            memcpy(params->tp_preferred_address.cid.idbuf, q, tlen);
1018            params->tp_preferred_address.cid.len = tlen;
1019            q += tlen;
1020            EXPECT_AT_LEAST(sizeof(params->tp_preferred_address.srst));
1021            memcpy(params->tp_preferred_address.srst, q,
1022                            sizeof(params->tp_preferred_address.srst));
1023            q += sizeof(params->tp_preferred_address.srst);
1024            if (q != p + len)
1025                return -1;
1026            break;
1027        default:
1028            /* Do nothing: skip this transport parameter */
1029            break;
1030        }
1031        p += len;
1032        if (tpi <= LAST_TPI)
1033        {
1034            params->tp_set |= 1 << tpi;
1035            params->tp_decoded |= 1 << tpi;
1036        }
1037    }
1038
1039    if (p != end)
1040        return -1;
1041
1042    if ((params->tp_set & (1 << TPI_MIN_ACK_DELAY))
1043            && params->tp_numerics[TPI_MIN_ACK_DELAY]
1044                            > params->tp_numerics[TPI_MAX_ACK_DELAY] * 1000)
1045    {
1046        LSQ_DEBUG("min_ack_delay (%"PRIu64" usec) is larger than "
1047            "max_ack_delay (%"PRIu64" ms)",
1048            params->tp_numerics[TPI_MIN_ACK_DELAY],
1049            params->tp_numerics[TPI_MAX_ACK_DELAY]);
1050        return -1;
1051    }
1052
1053    return (int) (end - buf);
1054#undef EXPECT_LEN
1055}
1056