lsquic_parse_gquic_be.c revision 2f2f4363
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_parse_gquic_be.c -- Parsing functions specific to big-endian
4 *                              (now only Q043) GQUIC.
5 */
6
7#include <assert.h>
8#include <inttypes.h>
9#include <errno.h>
10#include <stdlib.h>
11#include <string.h>
12#include <sys/queue.h>
13#ifndef WIN32
14#include <sys/types.h>
15#else
16#include <vc_compat.h>
17#endif
18
19#include "lsquic_types.h"
20#include "lsquic_int_types.h"
21#include "lsquic_packet_common.h"
22#include "lsquic_packet_in.h"
23#include "lsquic_packet_out.h"
24#include "lsquic_parse.h"
25#include "lsquic_parse_common.h"
26#include "lsquic_rechist.h"
27#include "lsquic_sfcw.h"
28#include "lsquic_varint.h"
29#include "lsquic_hq.h"
30#include "lsquic_hash.h"
31#include "lsquic_stream.h"
32#include "lsquic_mm.h"
33#include "lsquic_malo.h"
34#include "lsquic_version.h"
35#include "lsquic.h"
36#include "lsquic_conn.h"
37#include "lsquic_parse_gquic_be.h"  /* Include to catch mismatches */
38#include "lsquic_byteswap.h"
39
40#define LSQUIC_LOGGER_MODULE LSQLM_PARSE
41#include "lsquic_logger.h"
42
43
44/* read 16 bits(2 bytes) time, unit: us */
45uint64_t
46lsquic_gquic_be_read_float_time16 (const void *mem)
47{
48    uint16_t val;
49    READ_UINT(val, 16, mem, 2);
50    uint64_t temp = val;
51    uint16_t exp = (temp >> 11) & 0x1F;
52    if (0 == exp)
53        return temp;
54    else
55    {
56        --exp;
57        temp &= 0x7FF;
58        temp |= 0x800;
59        return temp << exp;
60    }
61}
62
63
64void
65lsquic_gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem)
66{
67    uint16_t ret = 0;
68    uint16_t high, i;
69
70    if (time_us < ((uint64_t)1 << 11))
71        ret = time_us;
72    else if(time_us > 0x3FFC0000000)
73        ret = 0xFFFF;
74    else
75    {
76        high = 0;
77        for (i = 16; i > 0; i /= 2)
78        {
79            if (time_us >= (uint64_t)1 << (11 + i))
80            {
81                high |= i;
82                time_us >>= i;
83            }
84        }
85        ret = time_us + (high << 11);
86    }
87#if __BYTE_ORDER == __LITTLE_ENDIAN
88    ret = bswap_16(ret);
89#endif
90    memcpy(mem, (void *)&ret, 2);
91}
92
93
94/* Parse out packet number */
95void
96lsquic_gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
97                                            struct packin_parse_state *state)
98{
99    lsquic_packno_t packno;
100    if (state->pps_nbytes)
101    {
102        READ_UINT(packno, 64, state->pps_p, state->pps_nbytes);
103        packet_in->pi_packno = packno;
104    }
105}
106
107
108static int
109lsquic_gquic_be_gen_reg_pkt_header (const struct lsquic_conn *lconn,
110            const struct lsquic_packet_out *packet_out, unsigned char *buf,
111        size_t bufsz, unsigned *packno_off_UNUSED, unsigned *packno_len_UNUSED)
112{
113    unsigned packnum_len, header_len;
114    enum packno_bits bits;
115    lsquic_packno_t packno;
116    unsigned char *p;
117
118    bits = lsquic_packet_out_packno_bits(packet_out);
119    packnum_len = gquic_packno_bits2len(bits);
120
121    if (0 == (packet_out->po_flags & (PO_CONN_ID|PO_VERSION|PO_NONCE)))
122    {
123        header_len = 1 + packnum_len;
124        if (header_len > bufsz)
125        {
126            errno = ENOBUFS;
127            return -1;
128        }
129        p = buf;
130        *p = bits << 4;
131        ++p;
132    }
133    else
134    {
135        const int
136            have_cid = packet_out->po_flags & PO_CONN_ID,
137            have_ver = packet_out->po_flags & PO_VERSION,
138            have_nonce = packet_out->po_flags & PO_NONCE;
139        header_len = 1
140                   + (!!have_cid << 3)
141                   + (!!have_ver << 2)
142                   + (!!have_nonce << 5)
143                   + packnum_len
144                   ;
145        if (header_len > bufsz)
146        {
147            errno = ENOBUFS;
148            return -1;
149        }
150
151        p =  buf;
152
153        *p = (!!have_cid << 3)
154           | (bits << 4)
155           | ((!!have_nonce) << 2)
156           | !!have_ver;
157        ++p;
158
159        if (have_cid)
160        {
161            assert(lconn->cn_cid.len == GQUIC_CID_LEN);
162            memcpy(p, lconn->cn_cid.idbuf, lconn->cn_cid.len);
163            p += lconn->cn_cid.len;
164        }
165
166        if (have_ver)
167        {
168            memcpy(p, &packet_out->po_ver_tag, 4);
169            p += 4;
170        }
171
172        if (have_nonce)
173        {
174            memcpy(p, packet_out->po_nonce , 32);
175            p += 32;
176        }
177    }
178
179    packno = packet_out->po_packno;
180#if __BYTE_ORDER == __LITTLE_ENDIAN
181    packno = bswap_64(packno);
182#endif
183    memcpy(p, (unsigned char *) &packno + 8 - packnum_len, packnum_len);
184    p += packnum_len;
185
186    assert(p - buf == (intptr_t) header_len);
187
188    return header_len;
189}
190
191
192int
193lsquic_gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len,
194        lsquic_stream_id_t stream_id64, uint64_t offset, int fin, size_t size,
195        gsf_read_f gsf_read, void *stream)
196{
197    /* 1fdoooss */
198    uint32_t stream_id = stream_id64;
199    unsigned slen, olen, dlen;
200    unsigned char *p = buf + 1;
201
202    /* ss: Stream ID length: 1, 2, 3, or 4 bytes */
203    slen = (stream_id > 0x0000FF)
204         + (stream_id > 0x00FFFF)
205         + (stream_id > 0xFFFFFF)
206         + 1;
207
208    /* ooo: Offset length: 0, 2, 3, 4, 5, 6, 7, or 8 bytes */
209    olen = (offset >= (1ULL << 56))
210         + (offset >= (1ULL << 48))
211         + (offset >= (1ULL << 40))
212         + (offset >= (1ULL << 32))
213         + (offset >= (1ULL << 24))
214         + (offset >= (1ULL << 16))
215         + ((offset > 0) << 1);
216
217    if (!fin)
218    {
219        unsigned n_avail;
220        uint16_t nr;
221
222        n_avail = buf_len - (p + slen + olen - buf);
223
224        /* If we cannot fill remaining buffer, we need to include data
225         * length.
226         */
227        dlen = (size < n_avail) << 1;
228        n_avail -= dlen;
229
230        CHECK_STREAM_SPACE(1 + olen + slen + dlen +
231            + 1 /* We need to write at least 1 byte */, buf, buf + buf_len);
232
233#if __BYTE_ORDER == __LITTLE_ENDIAN
234        stream_id = bswap_32(stream_id);
235#endif
236        memcpy(p, (unsigned char *) &stream_id + 4 - slen, slen);
237        p += slen;
238
239#if __BYTE_ORDER == __LITTLE_ENDIAN
240        offset = bswap_64(offset);
241#endif
242        memcpy(p, (unsigned char *) &offset + 8 - olen, olen);
243        p += olen;
244
245        /* Read as much as we can */
246        nr = gsf_read(stream, p + dlen, n_avail, &fin);
247        assert(nr != 0);
248
249        if (dlen)
250        {
251            uint16_t nr_copy = nr;
252#if __BYTE_ORDER == __LITTLE_ENDIAN
253            nr_copy = bswap_16(nr_copy);
254#endif
255            memcpy(p, &nr_copy, 2);
256        }
257
258        p += dlen + nr;
259    }
260    else
261    {
262        dlen = 2;
263        CHECK_STREAM_SPACE(1 + slen + olen + 2, buf, buf + buf_len);
264#if __BYTE_ORDER == __LITTLE_ENDIAN
265        stream_id = bswap_32(stream_id);
266#endif
267        memcpy(p, (unsigned char *) &stream_id + 4 - slen, slen);
268        p += slen;
269#if __BYTE_ORDER == __LITTLE_ENDIAN
270        offset = bswap_64(offset);
271#endif
272        memcpy(p, (unsigned char *) &offset + 8 - olen, olen);
273        p += olen;
274        memset(p, 0, 2);
275        p += 2;
276    }
277
278    /* Convert slen to bit representation: 0 - 3: */
279    slen -= 1;
280    assert(slen <= 3);
281
282    /* Convert olen to bit representation: 0 - 7: */
283    olen += !olen;
284    olen -= 1;
285    assert(olen <= 7);
286
287    buf[0] = 0x80
288           | (fin << 6)
289           | (dlen << 4)
290           | (olen << 2)
291           | slen
292           ;
293    return p - buf;
294}
295
296int
297lsquic_gquic_be_dec_stream_frame_size (unsigned char *buf, size_t new_size)
298{
299    /* 1fdoooss */
300    const unsigned char type = buf[0];
301
302    if (!(type & 0x20))
303        return 1;
304
305    const unsigned offset_len = ((type >> 2) & 7) + 1 - !((type >> 2) & 7);
306    const unsigned stream_id_len = 1 + (type & 3);
307
308    uint16_t len = new_size;
309#if __BYTE_ORDER == __LITTLE_ENDIAN
310    len = bswap_16(len);
311#endif
312    memcpy(buf + 1 + offset_len + stream_id_len, &len, 2);
313    return 0;
314}
315
316
317/* return parsed (used) buffer length */
318int
319lsquic_gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
320                       stream_frame_t *stream_frame)
321{
322    /* 1fdoooss */
323    uint32_t stream_id;
324    const unsigned char *p = buf;
325    const unsigned char *const pend = p + rem_packet_sz;
326
327    CHECK_SPACE(1, p, pend);
328    const char type = *p++;
329
330    const unsigned data_len   = (type >> 4) & 2;
331    const unsigned offset_len = ((type >> 2) & 7) + 1 - !((type >> 2) & 7);
332    const unsigned stream_id_len = 1 + (type & 3);
333    const unsigned need = data_len + offset_len + stream_id_len;
334    CHECK_SPACE(need, p, pend);
335
336    memset(stream_frame, 0, sizeof(*stream_frame));
337
338    stream_frame->data_frame.df_fin = (type >> 6) & 1;
339
340    stream_id = 0;
341    memcpy((unsigned char *) &stream_id + 4 - stream_id_len, p, stream_id_len);
342
343#if __BYTE_ORDER == __LITTLE_ENDIAN
344    stream_id = bswap_32(stream_id);
345#endif
346    stream_frame->stream_id = stream_id;
347    p += stream_id_len;
348
349    memcpy((unsigned char *) &stream_frame->data_frame.df_offset
350                                            + 8 - offset_len, p, offset_len);
351#if __BYTE_ORDER == __LITTLE_ENDIAN
352    stream_frame->data_frame.df_offset =
353                                bswap_64(stream_frame->data_frame.df_offset);
354#endif
355    p += offset_len;
356
357    if (data_len)
358    {
359        memcpy(&stream_frame->data_frame.df_size, p, data_len);
360#if __BYTE_ORDER == __LITTLE_ENDIAN
361        stream_frame->data_frame.df_size =
362                                bswap_16(stream_frame->data_frame.df_size);
363#endif
364        p += data_len;
365        CHECK_SPACE(stream_frame->data_frame.df_size, p, pend);
366        stream_frame->data_frame.df_data = p;
367        p += stream_frame->data_frame.df_size;
368    }
369    else
370    {
371        stream_frame->data_frame.df_size = pend - p;
372        stream_frame->data_frame.df_data = p;
373        p = pend;
374    }
375
376    /* From the spec: "A stream frame must always have either non-zero
377     * data length or the FIN bit set.'
378     */
379    if (!(stream_frame->data_frame.df_size ||
380                                        stream_frame->data_frame.df_fin))
381        return -1;
382
383    assert(p <= pend);
384
385    return p - (unsigned char *) buf;
386}
387
388
389static int
390parse_ack_frame_without_blocks (const unsigned char *buf, size_t buf_len,
391                                struct ack_info *ack)
392{
393    /* 01nullmm */
394    lsquic_packno_t tmp_packno;
395    const unsigned char type = buf[0];
396    const unsigned char *p = buf + 1;
397    const unsigned char *const pend = buf + buf_len;
398    unsigned char n_timestamps;
399
400    const int ack_block_len   = twobit_to_1246(type & 3);        /* mm */
401    const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */
402
403    CHECK_SPACE(largest_obs_len + 2 + ack_block_len + 1, p, pend);
404
405    READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
406    p += largest_obs_len;
407
408    ack->lack_delta = lsquic_gquic_be_read_float_time16(p);
409    p += 2;
410
411    READ_UINT(tmp_packno, 64, p, ack_block_len);
412    ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1;
413    p += ack_block_len;
414
415    ack->n_ranges = 1;
416
417    n_timestamps = *p;
418    ++p;
419
420    if (n_timestamps)
421    {
422        unsigned timestamps_size = 5 + 3 * (n_timestamps - 1);
423        CHECK_SPACE(timestamps_size, p, pend);
424        p += timestamps_size;
425    }
426
427    assert(p <= pend);
428
429    ack->flags = 0;
430    return p - (unsigned char *) buf;
431}
432
433
434static int
435parse_ack_frame_with_blocks (const unsigned char *buf, size_t buf_len,
436                                                        struct ack_info *ack)
437{
438    /* 01nullmm */
439    lsquic_packno_t tmp_packno;
440    const unsigned char type = buf[0];
441    const unsigned char *p = buf + 1;
442    const unsigned char *const pend = buf + buf_len;
443    unsigned char n_timestamps;
444
445    assert((type & 0xC0) == 0x40);      /* We're passed correct frame type */
446
447    const int ack_block_len   = twobit_to_1246(type & 3);        /* mm */
448    const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */
449
450    CHECK_SPACE(largest_obs_len + 2 + 1 + ack_block_len, p, pend);
451
452    READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
453    p += largest_obs_len;
454
455    ack->lack_delta = lsquic_gquic_be_read_float_time16(p);
456    p += 2;
457
458    unsigned n_blocks;
459    CHECK_SPACE(1, p , pend);
460    n_blocks = *p;
461    ++p;
462
463    READ_UINT(tmp_packno, 64, p, ack_block_len);
464    ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1;
465    p += ack_block_len;
466
467    CHECK_SPACE((ack_block_len + 1) * n_blocks + /* timestamp count: */ 1,
468                p , pend);
469    unsigned i, n, gap;
470    for (i = 0, n = 1, gap = 0; i < n_blocks; ++i)
471    {
472        uint64_t length;
473        gap += *p;
474        READ_UINT(length, 64, p + 1, ack_block_len);
475        p += 1 + ack_block_len;
476        if (length)
477        {
478            ack->ranges[n].high = ack->ranges[n - 1].low - gap - 1;
479            ack->ranges[n].low  = ack->ranges[n].high - length + 1;
480            ++n;
481            gap = 0;
482        }
483    }
484    ack->n_ranges = n;
485
486    n_timestamps = *p;
487    ++p;
488
489    if (n_timestamps)
490    {
491        unsigned timestamps_size = 5 + 3 * (n_timestamps - 1);
492        CHECK_SPACE(timestamps_size, p, pend);
493        p += timestamps_size;
494    }
495
496    assert(p <= pend);
497
498    ack->flags = 0;
499    return p - (unsigned char *) buf;
500}
501
502
503/* Return parsed (used) buffer length.
504 * If parsing failed, negative value is returned.
505 */
506int
507lsquic_gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
508                                    struct ack_info *ack, uint8_t UNUSED_exp)
509{
510    if (!(buf[0] & 0x20))
511        return parse_ack_frame_without_blocks(buf, buf_len, ack);
512    else
513        return parse_ack_frame_with_blocks(buf, buf_len, ack);
514}
515
516
517int
518lsquic_gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
519                lsquic_packno_t cur_packno, enum packno_bits bits,
520                lsquic_packno_t least_unacked_packno)
521{
522    lsquic_packno_t delta;
523    unsigned packnum_len = gquic_packno_bits2len(bits);
524
525    if (buf_len >= 1 + packnum_len)
526    {
527        *buf = 0x06;
528        delta = cur_packno - least_unacked_packno;
529#if __BYTE_ORDER == __LITTLE_ENDIAN
530        delta = bswap_64(delta);
531#endif
532        memcpy(buf + 1, (unsigned char *) &delta + 8 - packnum_len,
533                                                            packnum_len);
534        return 1 + packnum_len;
535    }
536    else
537        return -1;
538}
539
540
541int
542lsquic_gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
543                 lsquic_packno_t cur_packno, enum packno_bits bits,
544                 lsquic_packno_t *least_unacked)
545{
546    lsquic_packno_t delta;
547    unsigned packnum_len = gquic_packno_bits2len(bits);
548
549    if (buf_len >= 1 + packnum_len)
550    {
551        READ_UINT(delta, 64, buf + 1, packnum_len);
552        *least_unacked = cur_packno - delta;
553        return 1 + packnum_len;
554    }
555    else
556        return -1;
557}
558
559
560int
561lsquic_gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits)
562{
563    unsigned packnum_len = gquic_packno_bits2len(bits);
564    if (buf_len >= 1 + packnum_len)
565        return 1 + packnum_len;
566    else
567        return -1;
568}
569
570
571int
572lsquic_gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
573                            lsquic_stream_id_t stream_id64, uint64_t offset)
574{
575    uint32_t stream_id = stream_id64;
576
577    if (buf_len < GQUIC_WUF_SZ)
578        return -1;
579
580    *buf = 0x04;
581#if __BYTE_ORDER == __LITTLE_ENDIAN
582    stream_id = bswap_32(stream_id);
583#endif
584    memcpy(buf + 1, (unsigned char *) &stream_id, 4);
585#if __BYTE_ORDER == __LITTLE_ENDIAN
586    offset = bswap_64(offset);
587#endif
588    memcpy(buf + 1 + 4, (unsigned char *) &offset, 8);
589    return GQUIC_WUF_SZ;
590}
591
592
593int
594lsquic_gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
595                      lsquic_stream_id_t *stream_id_p, uint64_t *offset)
596{
597    uint32_t stream_id;
598
599    if (buf_len < GQUIC_WUF_SZ)
600        return -1;
601
602    READ_UINT(stream_id, 32, buf + 1, 4);
603    READ_UINT(*offset, 64, buf + 1 + 4, 8);
604    *stream_id_p = stream_id;
605    return GQUIC_WUF_SZ;
606}
607
608
609int
610lsquic_gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
611                            lsquic_stream_id_t stream_id64)
612{
613    uint32_t stream_id = stream_id64;
614
615    if (buf_len < GQUIC_BLOCKED_FRAME_SZ)
616        return -1;
617
618    *buf = 0x05;
619#if __BYTE_ORDER == __LITTLE_ENDIAN
620    stream_id = bswap_32(stream_id);
621#endif
622    memcpy(buf + 1, &stream_id, 4);
623    return GQUIC_BLOCKED_FRAME_SZ;
624}
625
626
627int
628lsquic_gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
629                                            lsquic_stream_id_t *stream_id_p)
630{
631    uint32_t stream_id;
632    if (buf_len < GQUIC_BLOCKED_FRAME_SZ)
633        return -1;
634
635    READ_UINT(stream_id, 32, buf + 1, 4);
636    *stream_id_p = stream_id;
637    return GQUIC_BLOCKED_FRAME_SZ;
638}
639
640
641static unsigned
642lsquic_gquic_be_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code,
643                                                        uint64_t final_size)
644{
645    assert(0);  /* This function is not called */
646    return GQUIC_RST_STREAM_SZ;
647}
648
649
650int
651lsquic_gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
652        lsquic_stream_id_t stream_id64, uint64_t offset, uint64_t error_code64)
653{
654    uint32_t stream_id = stream_id64, error_code = error_code64;
655    unsigned char *p = buf;
656    if (buf_len < GQUIC_RST_STREAM_SZ)
657        return -1;
658
659    *p = 0x01;
660    ++p;
661#if __BYTE_ORDER == __LITTLE_ENDIAN
662    stream_id = bswap_32(stream_id);
663#endif
664    memcpy(p, &stream_id, 4);
665    p += 4;
666#if __BYTE_ORDER == __LITTLE_ENDIAN
667    offset = bswap_64(offset);
668#endif
669    memcpy(p, &offset, 8);
670    p += 8;
671#if __BYTE_ORDER == __LITTLE_ENDIAN
672    error_code = bswap_32(error_code);
673#endif
674    memcpy(p, &error_code, 4);
675    p += 4;
676    return p - buf;
677}
678
679
680int
681lsquic_gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
682    lsquic_stream_id_t *stream_id_p, uint64_t *offset, uint64_t *error_code_p)
683{
684    uint32_t stream_id, error_code;
685
686    if (buf_len < GQUIC_RST_STREAM_SZ)
687        return -1;
688
689    READ_UINT(stream_id, 32, buf + 1, 4);
690    READ_UINT(*offset, 64, buf + 1 + 4, 8);
691    READ_UINT(error_code, 32, buf + 1 + 4 + 8, 4);
692    *stream_id_p = stream_id;
693    *error_code_p = error_code;
694    return GQUIC_RST_STREAM_SZ;
695}
696
697
698int
699lsquic_gquic_be_gen_ping_frame (unsigned char *buf, int buf_len)
700{
701    if (buf_len > 0)
702    {
703        buf[0] = 0x07;
704        return 1;
705    }
706    else
707        return -1;
708}
709
710
711size_t
712lsquic_gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
713                                unsigned frame_type, size_t reason_len)
714{
715    return 1 + 4 + 2 + reason_len;
716}
717
718
719int
720lsquic_gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
721    int app_error_UNUSED, unsigned ecode, const char *reason, int reason_len)
722{
723    uint32_t error_code;
724    unsigned char *p = buf;
725    if ((int) buf_len < 7 + reason_len)
726        return -1;
727
728    *p = 0x02;
729    ++p;
730    error_code = ecode;
731#if __BYTE_ORDER == __LITTLE_ENDIAN
732    error_code = bswap_32(error_code);
733#endif
734    memcpy(p, &error_code, 4);
735    p += 4;
736#if __BYTE_ORDER == __LITTLE_ENDIAN
737    const uint16_t copy = bswap_16(reason_len);
738    memcpy(p, &copy, 2);
739#else
740    memcpy(p, &reason_len, 2);
741#endif
742    p += 2;
743    memcpy(p, reason, reason_len);
744    p += reason_len;
745
746    return p - buf;
747}
748
749
750int
751lsquic_gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
752        int *app_error, uint64_t *error_code_p,
753        uint16_t *reason_len, uint8_t *reason_offset)
754{
755    uint32_t error_code;
756
757    if (buf_len < 7)
758        return -1;
759
760    READ_UINT(error_code, 32, buf + 1, 4);
761    READ_UINT(*reason_len, 16, buf + 1 + 4, 2);
762    *reason_offset = 7;
763    if (buf_len < 7u + *reason_len)
764        return -2;
765
766    *error_code_p = error_code;
767    if (app_error)
768        *app_error = 0;
769
770    return 7 + *reason_len;
771}
772
773
774int
775lsquic_gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len,
776        uint32_t error_code, lsquic_stream_id_t last_good_stream_id64,
777        const char *reason, size_t reason_len)
778{
779    uint32_t last_good_stream_id = last_good_stream_id64;
780    unsigned char *p = buf;
781    if (buf_len < GQUIC_GOAWAY_FRAME_SZ + reason_len)
782        return -1;
783
784    *p = 0x03;
785    ++p;
786#if __BYTE_ORDER == __LITTLE_ENDIAN
787    error_code = bswap_32(error_code);
788#endif
789    memcpy(p, &error_code, 4);
790    p += 4;
791#if __BYTE_ORDER == __LITTLE_ENDIAN
792    last_good_stream_id = bswap_32(last_good_stream_id);
793#endif
794    memcpy(p, &last_good_stream_id, 4);
795    p += 4;
796#if __BYTE_ORDER == __LITTLE_ENDIAN
797    uint16_t copy = bswap_16(reason_len);
798    memcpy(p, &copy, 2);
799#else
800    memcpy(p, &reason_len, 2);
801#endif
802    p += 2;
803    if (reason_len)
804    {
805        memcpy(p, reason, reason_len);
806        p += reason_len;
807    }
808
809    return p - buf;
810}
811
812
813/* the reason is buf + *reason_offset, length is *reason_length */
814int
815lsquic_gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
816               uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
817               uint16_t *reason_length, const char **reason)
818{
819    uint32_t stream_id;
820    if (buf_len < GQUIC_GOAWAY_FRAME_SZ)
821        return -1;
822
823    READ_UINT(*error_code,          32, buf + 1,         4);
824    READ_UINT(stream_id,            32, buf + 1 + 4,     4);
825    READ_UINT(*reason_length,       16, buf + 1 + 4 + 4, 2);
826    if (*reason_length)
827    {
828        if ((int)buf_len < GQUIC_GOAWAY_FRAME_SZ + *reason_length)
829            return -2;
830        *reason = (const char *) buf + GQUIC_GOAWAY_FRAME_SZ;
831    }
832    else
833        *reason = NULL;
834
835    *last_good_stream_id = stream_id;
836    return GQUIC_GOAWAY_FRAME_SZ + *reason_length;
837}
838
839
840/* Returns number of bytes written or -1 on failure */
841/* This function makes an assumption that there is at least one range */
842int
843lsquic_gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
844        gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next,
845        gaf_rechist_largest_recv_f rechist_largest_recv,
846        void *rechist, lsquic_time_t now, int *has_missing,
847        lsquic_packno_t *largest_received, const uint64_t *unused)
848{
849    lsquic_time_t time_diff;
850    lsquic_packno_t tmp_packno;
851    const struct lsquic_packno_range *const first = rechist_first(rechist);
852    if (!first)
853    {
854        errno = EINVAL;
855        return -1;
856    }
857
858    /* Copy values from the first range, because the memory the pointer
859     * points to may change:
860     */
861    const lsquic_packno_t first_low = first->low, first_high = first->high;
862
863    unsigned char *p = outbuf;
864    unsigned char *const type = p;
865    unsigned char *const end = p + outbuf_sz;
866
867#define AVAIL() (end - p)
868
869#define CHECKOUT(sz) do {                                               \
870    if ((intptr_t) (sz) > AVAIL()) {                                    \
871        errno = ENOBUFS;                                                \
872        return -1;                                                      \
873    }                                                                   \
874} while (0)
875
876    CHECKOUT(1);
877    ++p;
878
879    /* 01nullmm */
880    *type = 0x40;
881
882    unsigned largest_acked_len, ack_block_len, bits;
883
884    /* Calculate largest ACKed len and set `ll' bits: */
885    const lsquic_packno_t maxno = first_high;
886    bits = (maxno >= (1ULL <<  8))
887         + (maxno >= (1ULL << 16))
888         + (maxno >= (1ULL << 32));
889    largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1);
890    *type |= bits << 2;
891
892    /* Calculate largest ACK block length and set `mm' bits: */
893    unsigned n_ranges = 0;
894    lsquic_packno_t maxdiff = 0;
895    const struct lsquic_packno_range *range;
896    for (range = rechist_first(rechist); range; range = rechist_next(rechist))
897    {
898        ++n_ranges;
899        const lsquic_packno_t diff = range->high - range->low + 1;
900        if (diff > maxdiff)
901            maxdiff = diff;
902    }
903    bits = (maxdiff >= (1ULL <<  8))
904         + (maxdiff >= (1ULL << 16))
905         + (maxdiff >= (1ULL << 32));
906    ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1);
907    *type |= bits;
908
909    CHECKOUT(largest_acked_len);
910#if __BYTE_ORDER == __LITTLE_ENDIAN
911    tmp_packno = bswap_64(maxno);
912#else
913    tmp_packno = maxno;
914#endif
915    memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len,
916                                                            largest_acked_len);
917    p += largest_acked_len;
918
919    CHECKOUT(2);
920    time_diff = now - rechist_largest_recv(rechist);
921    lsquic_gquic_be_write_float_time16(time_diff, p);
922    LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff,
923        *(uint16_t*)p);
924    p += 2;
925
926    if (n_ranges > 1)
927    {
928        *has_missing = 1;
929        *type |= 0x20;
930        /* We need to write out at least one range */
931        CHECKOUT(2 * (1 + ack_block_len));
932        unsigned char *const n_ranges_p = p;             /* Set this later */
933        lsquic_packno_t diff = maxno - first_low + 1;
934#if __BYTE_ORDER == __LITTLE_ENDIAN
935        diff = bswap_64(diff);
936#endif
937        memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len,
938                                                            ack_block_len);
939        p += ack_block_len + 1;
940        /* Write out ack blocks until one of the following occurs:
941         *  1. We run out of intervals.
942         *  2. We run out of room.
943         *  3. We run out of highest possible number of ACK blocks (0xFF).
944         */
945        range = rechist_first(rechist);
946        lsquic_packno_t gap = 0;
947        n_ranges = 0;
948        do {
949            if (0 == gap)
950            {
951                const lsquic_packno_t prev_low = range->low;
952                range = rechist_next(rechist);
953                if (!range)
954                    break;
955                gap = prev_low - range->high - 1;
956            }
957            if (gap >= 0x100)
958            {
959                *p = 0xFF;
960                gap -= 0xFF;
961                memset(p + 1, 0, ack_block_len);
962            }
963            else
964            {
965                *p = gap;
966                gap = 0;
967                diff = range->high - range->low + 1;
968#if __BYTE_ORDER == __LITTLE_ENDIAN
969                diff = bswap_64(diff);
970#endif
971                memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len,
972                                                                ack_block_len);
973            }
974            p += ack_block_len + 1;
975            ++n_ranges;
976        } while (n_ranges < 0xFF &&
977                 AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */);
978        *n_ranges_p = n_ranges;
979    }
980    else
981    {
982        *has_missing = 0;
983        CHECKOUT(ack_block_len);
984        lsquic_packno_t diff = maxno - first_low + 1;
985#if __BYTE_ORDER == __LITTLE_ENDIAN
986        diff = bswap_64(diff);
987#endif
988        memcpy(p, (unsigned char *) &diff + 8 - ack_block_len, ack_block_len);
989        p += ack_block_len;
990    }
991
992    /* We do not generate timestamp list because the reference implementation
993     * does not use them.  When that changes, we will start sending timestamps
994     * over.
995     */
996    CHECKOUT(1);
997    *p = 0;
998    ++p;
999
1000    *largest_received = maxno;
1001    return p - (unsigned char *) outbuf;
1002
1003#undef CHECKOUT
1004}
1005
1006
1007static int
1008lsquic_gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
1009        lsquic_stream_id_t stream_if, uint64_t offset, int fin,
1010        size_t size, gsf_read_f gsf_read, void *stream)
1011{
1012    assert(0);
1013    return -1;
1014}
1015
1016
1017static int
1018lsquic_gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
1019                                            struct stream_frame *stream_frame)
1020{
1021    assert(0);
1022    return -1;
1023}
1024
1025
1026static unsigned
1027gquic_Q043_handshake_done_frame_size (void)
1028{
1029    return 0;
1030}
1031
1032
1033static int
1034gquic_Q043_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
1035{
1036    return -1;
1037}
1038
1039
1040static int
1041gquic_Q043_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
1042{
1043    return -1;
1044}
1045
1046
1047const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
1048{
1049    .pf_gen_reg_pkt_header            =  lsquic_gquic_be_gen_reg_pkt_header,
1050    .pf_parse_packet_in_finish        =  lsquic_gquic_be_parse_packet_in_finish,
1051    .pf_gen_stream_frame              =  lsquic_gquic_be_gen_stream_frame,
1052    .pf_calc_stream_frame_header_sz   =  lsquic_calc_stream_frame_header_sz_gquic,
1053    .pf_parse_stream_frame            =  lsquic_gquic_be_parse_stream_frame,
1054    .pf_parse_ack_frame               =  lsquic_gquic_be_parse_ack_frame,
1055    .pf_dec_stream_frame_size         =  lsquic_gquic_be_dec_stream_frame_size,
1056    .pf_gen_ack_frame                 =  lsquic_gquic_be_gen_ack_frame,
1057    .pf_gen_stop_waiting_frame        =  lsquic_gquic_be_gen_stop_waiting_frame,
1058    .pf_parse_stop_waiting_frame      =  lsquic_gquic_be_parse_stop_waiting_frame,
1059    .pf_skip_stop_waiting_frame       =  lsquic_gquic_be_skip_stop_waiting_frame,
1060    .pf_gen_window_update_frame       =  lsquic_gquic_be_gen_window_update_frame,
1061    .pf_parse_window_update_frame     =  lsquic_gquic_be_parse_window_update_frame,
1062    .pf_gen_blocked_frame             =  lsquic_gquic_be_gen_blocked_frame,
1063    .pf_parse_blocked_frame           =  lsquic_gquic_be_parse_blocked_frame,
1064    .pf_rst_frame_size                =  lsquic_gquic_be_rst_frame_size,
1065    .pf_gen_rst_frame                 =  lsquic_gquic_be_gen_rst_frame,
1066    .pf_parse_rst_frame               =  lsquic_gquic_be_parse_rst_frame,
1067    .pf_connect_close_frame_size      =  lsquic_gquic_be_connect_close_frame_size,
1068    .pf_gen_connect_close_frame       =  lsquic_gquic_be_gen_connect_close_frame,
1069    .pf_parse_connect_close_frame     =  lsquic_gquic_be_parse_connect_close_frame,
1070    .pf_gen_goaway_frame              =  lsquic_gquic_be_gen_goaway_frame,
1071    .pf_parse_goaway_frame            =  lsquic_gquic_be_parse_goaway_frame,
1072    .pf_gen_ping_frame                =  lsquic_gquic_be_gen_ping_frame,
1073#ifndef NDEBUG
1074    .pf_write_float_time16            =  lsquic_gquic_be_write_float_time16,
1075    .pf_read_float_time16             =  lsquic_gquic_be_read_float_time16,
1076#endif
1077    .pf_generate_simple_prst          =  lsquic_generate_gquic_reset,
1078    .pf_parse_frame_type              =  lsquic_parse_frame_type_gquic_Q035_thru_Q046,
1079    .pf_turn_on_fin                   =  lsquic_turn_on_fin_Q035_thru_Q046,
1080    .pf_packout_size                  =  lsquic_gquic_packout_size,
1081    .pf_packout_max_header_size       =  lsquic_gquic_packout_header_size,
1082    .pf_calc_packno_bits              =  lsquic_gquic_calc_packno_bits,
1083    .pf_packno_bits2len               =  lsquic_gquic_packno_bits2len,
1084    .pf_gen_crypto_frame              =  lsquic_gquic_be_gen_crypto_frame,
1085    .pf_parse_crypto_frame            =  lsquic_gquic_be_parse_crypto_frame,
1086    .pf_gen_handshake_done_frame      =  gquic_Q043_gen_handshake_done_frame,
1087    .pf_parse_handshake_done_frame    =  gquic_Q043_parse_handshake_done_frame,
1088    .pf_handshake_done_frame_size     =  gquic_Q043_handshake_done_frame_size,
1089};
1090