lsquic_parse_gquic_be.c revision b8fa6195
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)
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
296
297/* return parsed (used) buffer length */
298int
299lsquic_gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
300                       stream_frame_t *stream_frame)
301{
302    /* 1fdoooss */
303    uint32_t stream_id;
304    const unsigned char *p = buf;
305    const unsigned char *const pend = p + rem_packet_sz;
306
307    CHECK_SPACE(1, p, pend);
308    const char type = *p++;
309
310    const unsigned data_len   = (type >> 4) & 2;
311    const unsigned offset_len = ((type >> 2) & 7) + 1 - !((type >> 2) & 7);
312    const unsigned stream_id_len = 1 + (type & 3);
313    const unsigned need = data_len + offset_len + stream_id_len;
314    CHECK_SPACE(need, p, pend);
315
316    memset(stream_frame, 0, sizeof(*stream_frame));
317
318    stream_frame->data_frame.df_fin = (type >> 6) & 1;
319
320    stream_id = 0;
321    memcpy((unsigned char *) &stream_id + 4 - stream_id_len, p, stream_id_len);
322
323#if __BYTE_ORDER == __LITTLE_ENDIAN
324    stream_id = bswap_32(stream_id);
325#endif
326    stream_frame->stream_id = stream_id;
327    p += stream_id_len;
328
329    memcpy((unsigned char *) &stream_frame->data_frame.df_offset
330                                            + 8 - offset_len, p, offset_len);
331#if __BYTE_ORDER == __LITTLE_ENDIAN
332    stream_frame->data_frame.df_offset =
333                                bswap_64(stream_frame->data_frame.df_offset);
334#endif
335    p += offset_len;
336
337    if (data_len)
338    {
339        memcpy(&stream_frame->data_frame.df_size, p, data_len);
340#if __BYTE_ORDER == __LITTLE_ENDIAN
341        stream_frame->data_frame.df_size =
342                                bswap_16(stream_frame->data_frame.df_size);
343#endif
344        p += data_len;
345        CHECK_SPACE(stream_frame->data_frame.df_size, p, pend);
346        stream_frame->data_frame.df_data = p;
347        p += stream_frame->data_frame.df_size;
348    }
349    else
350    {
351        stream_frame->data_frame.df_size = pend - p;
352        stream_frame->data_frame.df_data = p;
353        p = pend;
354    }
355
356    /* From the spec: "A stream frame must always have either non-zero
357     * data length or the FIN bit set.'
358     */
359    if (!(stream_frame->data_frame.df_size ||
360                                        stream_frame->data_frame.df_fin))
361        return -1;
362
363    assert(p <= pend);
364
365    return p - (unsigned char *) buf;
366}
367
368
369static int
370parse_ack_frame_without_blocks (const unsigned char *buf, size_t buf_len,
371                                struct ack_info *ack)
372{
373    /* 01nullmm */
374    lsquic_packno_t tmp_packno;
375    const unsigned char type = buf[0];
376    const unsigned char *p = buf + 1;
377    const unsigned char *const pend = buf + buf_len;
378    unsigned char n_timestamps;
379
380    const int ack_block_len   = twobit_to_1246(type & 3);        /* mm */
381    const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */
382
383    CHECK_SPACE(largest_obs_len + 2 + ack_block_len + 1, p, pend);
384
385    READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
386    p += largest_obs_len;
387
388    ack->lack_delta = lsquic_gquic_be_read_float_time16(p);
389    p += 2;
390
391    READ_UINT(tmp_packno, 64, p, ack_block_len);
392    ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1;
393    p += ack_block_len;
394
395    ack->n_ranges = 1;
396
397    n_timestamps = *p;
398    ++p;
399
400    if (n_timestamps)
401    {
402        unsigned timestamps_size = 5 + 3 * (n_timestamps - 1);
403        CHECK_SPACE(timestamps_size, p, pend);
404        p += timestamps_size;
405    }
406
407    assert(p <= pend);
408
409    ack->flags = 0;
410    return p - (unsigned char *) buf;
411}
412
413
414static int
415parse_ack_frame_with_blocks (const unsigned char *buf, size_t buf_len,
416                                                        struct ack_info *ack)
417{
418    /* 01nullmm */
419    lsquic_packno_t tmp_packno;
420    const unsigned char type = buf[0];
421    const unsigned char *p = buf + 1;
422    const unsigned char *const pend = buf + buf_len;
423    unsigned char n_timestamps;
424
425    assert((type & 0xC0) == 0x40);      /* We're passed correct frame type */
426
427    const int ack_block_len   = twobit_to_1246(type & 3);        /* mm */
428    const int largest_obs_len = twobit_to_1246((type >> 2) & 3); /* ll */
429
430    CHECK_SPACE(largest_obs_len + 2 + 1 + ack_block_len, p, pend);
431
432    READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
433    p += largest_obs_len;
434
435    ack->lack_delta = lsquic_gquic_be_read_float_time16(p);
436    p += 2;
437
438    unsigned n_blocks;
439    CHECK_SPACE(1, p , pend);
440    n_blocks = *p;
441    ++p;
442
443    READ_UINT(tmp_packno, 64, p, ack_block_len);
444    ack->ranges[0].low = ack->ranges[0].high - tmp_packno + 1;
445    p += ack_block_len;
446
447    CHECK_SPACE((ack_block_len + 1) * n_blocks + /* timestamp count: */ 1,
448                p , pend);
449    unsigned i, n, gap;
450    for (i = 0, n = 1, gap = 0; i < n_blocks; ++i)
451    {
452        uint64_t length;
453        gap += *p;
454        READ_UINT(length, 64, p + 1, ack_block_len);
455        p += 1 + ack_block_len;
456        if (length)
457        {
458            ack->ranges[n].high = ack->ranges[n - 1].low - gap - 1;
459            ack->ranges[n].low  = ack->ranges[n].high - length + 1;
460            ++n;
461            gap = 0;
462        }
463    }
464    ack->n_ranges = n;
465
466    n_timestamps = *p;
467    ++p;
468
469    if (n_timestamps)
470    {
471        unsigned timestamps_size = 5 + 3 * (n_timestamps - 1);
472        CHECK_SPACE(timestamps_size, p, pend);
473        p += timestamps_size;
474    }
475
476    assert(p <= pend);
477
478    ack->flags = 0;
479    return p - (unsigned char *) buf;
480}
481
482
483/* Return parsed (used) buffer length.
484 * If parsing failed, negative value is returned.
485 */
486int
487lsquic_gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
488                                    struct ack_info *ack, uint8_t UNUSED_exp)
489{
490    if (!(buf[0] & 0x20))
491        return parse_ack_frame_without_blocks(buf, buf_len, ack);
492    else
493        return parse_ack_frame_with_blocks(buf, buf_len, ack);
494}
495
496
497int
498lsquic_gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
499                lsquic_packno_t cur_packno, enum packno_bits bits,
500                lsquic_packno_t least_unacked_packno)
501{
502    lsquic_packno_t delta;
503    unsigned packnum_len = gquic_packno_bits2len(bits);
504
505    if (buf_len >= 1 + packnum_len)
506    {
507        *buf = 0x06;
508        delta = cur_packno - least_unacked_packno;
509#if __BYTE_ORDER == __LITTLE_ENDIAN
510        delta = bswap_64(delta);
511#endif
512        memcpy(buf + 1, (unsigned char *) &delta + 8 - packnum_len,
513                                                            packnum_len);
514        return 1 + packnum_len;
515    }
516    else
517        return -1;
518}
519
520
521int
522lsquic_gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
523                 lsquic_packno_t cur_packno, enum packno_bits bits,
524                 lsquic_packno_t *least_unacked)
525{
526    lsquic_packno_t delta;
527    unsigned packnum_len = gquic_packno_bits2len(bits);
528
529    if (buf_len >= 1 + packnum_len)
530    {
531        READ_UINT(delta, 64, buf + 1, packnum_len);
532        *least_unacked = cur_packno - delta;
533        return 1 + packnum_len;
534    }
535    else
536        return -1;
537}
538
539
540int
541lsquic_gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits)
542{
543    unsigned packnum_len = gquic_packno_bits2len(bits);
544    if (buf_len >= 1 + packnum_len)
545        return 1 + packnum_len;
546    else
547        return -1;
548}
549
550
551int
552lsquic_gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
553                            lsquic_stream_id_t stream_id64, uint64_t offset)
554{
555    uint32_t stream_id = stream_id64;
556
557    if (buf_len < GQUIC_WUF_SZ)
558        return -1;
559
560    *buf = 0x04;
561#if __BYTE_ORDER == __LITTLE_ENDIAN
562    stream_id = bswap_32(stream_id);
563#endif
564    memcpy(buf + 1, (unsigned char *) &stream_id, 4);
565#if __BYTE_ORDER == __LITTLE_ENDIAN
566    offset = bswap_64(offset);
567#endif
568    memcpy(buf + 1 + 4, (unsigned char *) &offset, 8);
569    return GQUIC_WUF_SZ;
570}
571
572
573int
574lsquic_gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
575                      lsquic_stream_id_t *stream_id_p, uint64_t *offset)
576{
577    uint32_t stream_id;
578
579    if (buf_len < GQUIC_WUF_SZ)
580        return -1;
581
582    READ_UINT(stream_id, 32, buf + 1, 4);
583    READ_UINT(*offset, 64, buf + 1 + 4, 8);
584    *stream_id_p = stream_id;
585    return GQUIC_WUF_SZ;
586}
587
588
589int
590lsquic_gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
591                            lsquic_stream_id_t stream_id64)
592{
593    uint32_t stream_id = stream_id64;
594
595    if (buf_len < GQUIC_BLOCKED_FRAME_SZ)
596        return -1;
597
598    *buf = 0x05;
599#if __BYTE_ORDER == __LITTLE_ENDIAN
600    stream_id = bswap_32(stream_id);
601#endif
602    memcpy(buf + 1, &stream_id, 4);
603    return GQUIC_BLOCKED_FRAME_SZ;
604}
605
606
607int
608lsquic_gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
609                                            lsquic_stream_id_t *stream_id_p)
610{
611    uint32_t stream_id;
612    if (buf_len < GQUIC_BLOCKED_FRAME_SZ)
613        return -1;
614
615    READ_UINT(stream_id, 32, buf + 1, 4);
616    *stream_id_p = stream_id;
617    return GQUIC_BLOCKED_FRAME_SZ;
618}
619
620
621static unsigned
622lsquic_gquic_be_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code,
623                                                        uint64_t final_size)
624{
625    assert(0);  /* This function is not called */
626    return GQUIC_RST_STREAM_SZ;
627}
628
629
630int
631lsquic_gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
632        lsquic_stream_id_t stream_id64, uint64_t offset, uint64_t error_code64)
633{
634    uint32_t stream_id = stream_id64, error_code = error_code64;
635    unsigned char *p = buf;
636    if (buf_len < GQUIC_RST_STREAM_SZ)
637        return -1;
638
639    *p = 0x01;
640    ++p;
641#if __BYTE_ORDER == __LITTLE_ENDIAN
642    stream_id = bswap_32(stream_id);
643#endif
644    memcpy(p, &stream_id, 4);
645    p += 4;
646#if __BYTE_ORDER == __LITTLE_ENDIAN
647    offset = bswap_64(offset);
648#endif
649    memcpy(p, &offset, 8);
650    p += 8;
651#if __BYTE_ORDER == __LITTLE_ENDIAN
652    error_code = bswap_32(error_code);
653#endif
654    memcpy(p, &error_code, 4);
655    p += 4;
656    return p - buf;
657}
658
659
660int
661lsquic_gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
662    lsquic_stream_id_t *stream_id_p, uint64_t *offset, uint64_t *error_code_p)
663{
664    uint32_t stream_id, error_code;
665
666    if (buf_len < GQUIC_RST_STREAM_SZ)
667        return -1;
668
669    READ_UINT(stream_id, 32, buf + 1, 4);
670    READ_UINT(*offset, 64, buf + 1 + 4, 8);
671    READ_UINT(error_code, 32, buf + 1 + 4 + 8, 4);
672    *stream_id_p = stream_id;
673    *error_code_p = error_code;
674    return GQUIC_RST_STREAM_SZ;
675}
676
677
678int
679lsquic_gquic_be_gen_ping_frame (unsigned char *buf, int buf_len)
680{
681    if (buf_len > 0)
682    {
683        buf[0] = 0x07;
684        return 1;
685    }
686    else
687        return -1;
688}
689
690
691size_t
692lsquic_gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
693                                unsigned frame_type, size_t reason_len)
694{
695    return 1 + 4 + 2 + reason_len;
696}
697
698
699int
700lsquic_gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
701    int app_error_UNUSED, unsigned ecode, const char *reason, int reason_len)
702{
703    uint32_t error_code;
704    unsigned char *p = buf;
705    if ((int) buf_len < 7 + reason_len)
706        return -1;
707
708    *p = 0x02;
709    ++p;
710    error_code = ecode;
711#if __BYTE_ORDER == __LITTLE_ENDIAN
712    error_code = bswap_32(error_code);
713#endif
714    memcpy(p, &error_code, 4);
715    p += 4;
716#if __BYTE_ORDER == __LITTLE_ENDIAN
717    const uint16_t copy = bswap_16(reason_len);
718    memcpy(p, &copy, 2);
719#else
720    memcpy(p, &reason_len, 2);
721#endif
722    p += 2;
723    memcpy(p, reason, reason_len);
724    p += reason_len;
725
726    return p - buf;
727}
728
729
730int
731lsquic_gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
732        int *app_error, uint64_t *error_code_p,
733        uint16_t *reason_len, uint8_t *reason_offset)
734{
735    uint32_t error_code;
736
737    if (buf_len < 7)
738        return -1;
739
740    READ_UINT(error_code, 32, buf + 1, 4);
741    READ_UINT(*reason_len, 16, buf + 1 + 4, 2);
742    *reason_offset = 7;
743    if (buf_len < 7u + *reason_len)
744        return -2;
745
746    *error_code_p = error_code;
747    if (app_error)
748        *app_error = 0;
749
750    return 7 + *reason_len;
751}
752
753
754int
755lsquic_gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len,
756        uint32_t error_code, lsquic_stream_id_t last_good_stream_id64,
757        const char *reason, size_t reason_len)
758{
759    uint32_t last_good_stream_id = last_good_stream_id64;
760    unsigned char *p = buf;
761    if (buf_len < GQUIC_GOAWAY_FRAME_SZ + reason_len)
762        return -1;
763
764    *p = 0x03;
765    ++p;
766#if __BYTE_ORDER == __LITTLE_ENDIAN
767    error_code = bswap_32(error_code);
768#endif
769    memcpy(p, &error_code, 4);
770    p += 4;
771#if __BYTE_ORDER == __LITTLE_ENDIAN
772    last_good_stream_id = bswap_32(last_good_stream_id);
773#endif
774    memcpy(p, &last_good_stream_id, 4);
775    p += 4;
776#if __BYTE_ORDER == __LITTLE_ENDIAN
777    uint16_t copy = bswap_16(reason_len);
778    memcpy(p, &copy, 2);
779#else
780    memcpy(p, &reason_len, 2);
781#endif
782    p += 2;
783    if (reason_len)
784    {
785        memcpy(p, reason, reason_len);
786        p += reason_len;
787    }
788
789    return p - buf;
790}
791
792
793/* the reason is buf + *reason_offset, length is *reason_length */
794int
795lsquic_gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
796               uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
797               uint16_t *reason_length, const char **reason)
798{
799    uint32_t stream_id;
800    if (buf_len < GQUIC_GOAWAY_FRAME_SZ)
801        return -1;
802
803    READ_UINT(*error_code,          32, buf + 1,         4);
804    READ_UINT(stream_id,            32, buf + 1 + 4,     4);
805    READ_UINT(*reason_length,       16, buf + 1 + 4 + 4, 2);
806    if (*reason_length)
807    {
808        if ((int)buf_len < GQUIC_GOAWAY_FRAME_SZ + *reason_length)
809            return -2;
810        *reason = (const char *) buf + GQUIC_GOAWAY_FRAME_SZ;
811    }
812    else
813        *reason = NULL;
814
815    *last_good_stream_id = stream_id;
816    return GQUIC_GOAWAY_FRAME_SZ + *reason_length;
817}
818
819
820/* Returns number of bytes written or -1 on failure */
821/* This function makes an assumption that there is at least one range */
822int
823lsquic_gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
824        gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next,
825        gaf_rechist_largest_recv_f rechist_largest_recv,
826        void *rechist, lsquic_time_t now, int *has_missing,
827        lsquic_packno_t *largest_received, const uint64_t *unused)
828{
829    lsquic_time_t time_diff;
830    lsquic_packno_t tmp_packno;
831    const struct lsquic_packno_range *const first = rechist_first(rechist);
832    if (!first)
833    {
834        errno = EINVAL;
835        return -1;
836    }
837
838    /* Copy values from the first range, because the memory the pointer
839     * points to may change:
840     */
841    const lsquic_packno_t first_low = first->low, first_high = first->high;
842
843    unsigned char *p = outbuf;
844    unsigned char *const type = p;
845    unsigned char *const end = p + outbuf_sz;
846
847#define AVAIL() (end - p)
848
849#define CHECKOUT(sz) do {                                               \
850    if ((intptr_t) (sz) > AVAIL()) {                                    \
851        errno = ENOBUFS;                                                \
852        return -1;                                                      \
853    }                                                                   \
854} while (0)
855
856    CHECKOUT(1);
857    ++p;
858
859    /* 01nullmm */
860    *type = 0x40;
861
862    unsigned largest_acked_len, ack_block_len, bits;
863
864    /* Calculate largest ACKed len and set `ll' bits: */
865    const lsquic_packno_t maxno = first_high;
866    bits = (maxno >= (1ULL <<  8))
867         + (maxno >= (1ULL << 16))
868         + (maxno >= (1ULL << 32));
869    largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1);
870    *type |= bits << 2;
871
872    /* Calculate largest ACK block length and set `mm' bits: */
873    unsigned n_ranges = 0;
874    lsquic_packno_t maxdiff = 0;
875    const struct lsquic_packno_range *range;
876    for (range = rechist_first(rechist); range; range = rechist_next(rechist))
877    {
878        ++n_ranges;
879        const lsquic_packno_t diff = range->high - range->low + 1;
880        if (diff > maxdiff)
881            maxdiff = diff;
882    }
883    bits = (maxdiff >= (1ULL <<  8))
884         + (maxdiff >= (1ULL << 16))
885         + (maxdiff >= (1ULL << 32));
886    ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1);
887    *type |= bits;
888
889    CHECKOUT(largest_acked_len);
890#if __BYTE_ORDER == __LITTLE_ENDIAN
891    tmp_packno = bswap_64(maxno);
892#else
893    tmp_packno = maxno;
894#endif
895    memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len,
896                                                            largest_acked_len);
897    p += largest_acked_len;
898
899    CHECKOUT(2);
900    time_diff = now - rechist_largest_recv(rechist);
901    lsquic_gquic_be_write_float_time16(time_diff, p);
902    LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff,
903        *(uint16_t*)p);
904    p += 2;
905
906    if (n_ranges > 1)
907    {
908        *has_missing = 1;
909        *type |= 0x20;
910        /* We need to write out at least one range */
911        CHECKOUT(2 * (1 + ack_block_len));
912        unsigned char *const n_ranges_p = p;             /* Set this later */
913        lsquic_packno_t diff = maxno - first_low + 1;
914#if __BYTE_ORDER == __LITTLE_ENDIAN
915        diff = bswap_64(diff);
916#endif
917        memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len,
918                                                            ack_block_len);
919        p += ack_block_len + 1;
920        /* Write out ack blocks until one of the following occurs:
921         *  1. We run out of intervals.
922         *  2. We run out of room.
923         *  3. We run out of highest possible number of ACK blocks (0xFF).
924         */
925        range = rechist_first(rechist);
926        lsquic_packno_t gap = 0;
927        n_ranges = 0;
928        do {
929            if (0 == gap)
930            {
931                const lsquic_packno_t prev_low = range->low;
932                range = rechist_next(rechist);
933                if (!range)
934                    break;
935                gap = prev_low - range->high - 1;
936            }
937            if (gap >= 0x100)
938            {
939                *p = 0xFF;
940                gap -= 0xFF;
941                memset(p + 1, 0, ack_block_len);
942            }
943            else
944            {
945                *p = gap;
946                gap = 0;
947                diff = range->high - range->low + 1;
948#if __BYTE_ORDER == __LITTLE_ENDIAN
949                diff = bswap_64(diff);
950#endif
951                memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len,
952                                                                ack_block_len);
953            }
954            p += ack_block_len + 1;
955            ++n_ranges;
956        } while (n_ranges < 0xFF &&
957                 AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */);
958        *n_ranges_p = n_ranges;
959    }
960    else
961    {
962        *has_missing = 0;
963        CHECKOUT(ack_block_len);
964        lsquic_packno_t diff = maxno - first_low + 1;
965#if __BYTE_ORDER == __LITTLE_ENDIAN
966        diff = bswap_64(diff);
967#endif
968        memcpy(p, (unsigned char *) &diff + 8 - ack_block_len, ack_block_len);
969        p += ack_block_len;
970    }
971
972    /* We do not generate timestamp list because the reference implementation
973     * does not use them.  When that changes, we will start sending timestamps
974     * over.
975     */
976    CHECKOUT(1);
977    *p = 0;
978    ++p;
979
980    *largest_received = maxno;
981    return p - (unsigned char *) outbuf;
982
983#undef CHECKOUT
984}
985
986
987static int
988lsquic_gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
989        lsquic_stream_id_t stream_if, uint64_t offset, int fin,
990        size_t size, gsf_read_f gsf_read, void *stream)
991{
992    assert(0);
993    return -1;
994}
995
996
997static int
998lsquic_gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
999                                            struct stream_frame *stream_frame)
1000{
1001    assert(0);
1002    return -1;
1003}
1004
1005
1006static void
1007lsquic_gquic_be_packno_info (const struct lsquic_conn *lconn,
1008        const struct lsquic_packet_out *packet_out, unsigned *packno_off,
1009        unsigned *packno_len)
1010{
1011    assert(0);
1012}
1013
1014
1015static unsigned
1016gquic_Q043_handshake_done_frame_size (void)
1017{
1018    return 0;
1019}
1020
1021
1022static int
1023gquic_Q043_gen_handshake_done_frame (unsigned char *buf, size_t buf_len)
1024{
1025    return -1;
1026}
1027
1028
1029static int
1030gquic_Q043_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
1031{
1032    return -1;
1033}
1034
1035
1036const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
1037{
1038    .pf_gen_reg_pkt_header            =  lsquic_gquic_be_gen_reg_pkt_header,
1039    .pf_parse_packet_in_finish        =  lsquic_gquic_be_parse_packet_in_finish,
1040    .pf_gen_stream_frame              =  lsquic_gquic_be_gen_stream_frame,
1041    .pf_calc_stream_frame_header_sz   =  lsquic_calc_stream_frame_header_sz_gquic,
1042    .pf_parse_stream_frame            =  lsquic_gquic_be_parse_stream_frame,
1043    .pf_parse_ack_frame               =  lsquic_gquic_be_parse_ack_frame,
1044    .pf_gen_ack_frame                 =  lsquic_gquic_be_gen_ack_frame,
1045    .pf_gen_stop_waiting_frame        =  lsquic_gquic_be_gen_stop_waiting_frame,
1046    .pf_parse_stop_waiting_frame      =  lsquic_gquic_be_parse_stop_waiting_frame,
1047    .pf_skip_stop_waiting_frame       =  lsquic_gquic_be_skip_stop_waiting_frame,
1048    .pf_gen_window_update_frame       =  lsquic_gquic_be_gen_window_update_frame,
1049    .pf_parse_window_update_frame     =  lsquic_gquic_be_parse_window_update_frame,
1050    .pf_gen_blocked_frame             =  lsquic_gquic_be_gen_blocked_frame,
1051    .pf_parse_blocked_frame           =  lsquic_gquic_be_parse_blocked_frame,
1052    .pf_rst_frame_size                =  lsquic_gquic_be_rst_frame_size,
1053    .pf_gen_rst_frame                 =  lsquic_gquic_be_gen_rst_frame,
1054    .pf_parse_rst_frame               =  lsquic_gquic_be_parse_rst_frame,
1055    .pf_connect_close_frame_size      =  lsquic_gquic_be_connect_close_frame_size,
1056    .pf_gen_connect_close_frame       =  lsquic_gquic_be_gen_connect_close_frame,
1057    .pf_parse_connect_close_frame     =  lsquic_gquic_be_parse_connect_close_frame,
1058    .pf_gen_goaway_frame              =  lsquic_gquic_be_gen_goaway_frame,
1059    .pf_parse_goaway_frame            =  lsquic_gquic_be_parse_goaway_frame,
1060    .pf_gen_ping_frame                =  lsquic_gquic_be_gen_ping_frame,
1061#ifndef NDEBUG
1062    .pf_write_float_time16            =  lsquic_gquic_be_write_float_time16,
1063    .pf_read_float_time16             =  lsquic_gquic_be_read_float_time16,
1064#endif
1065    .pf_generate_simple_prst          =  lsquic_generate_gquic_reset,
1066    .pf_parse_frame_type              =  lsquic_parse_frame_type_gquic_Q035_thru_Q046,
1067    .pf_turn_on_fin                   =  lsquic_turn_on_fin_Q035_thru_Q046,
1068    .pf_packout_size                  =  lsquic_gquic_packout_size,
1069    .pf_packout_max_header_size       =  lsquic_gquic_packout_header_size,
1070    .pf_calc_packno_bits              =  lsquic_gquic_calc_packno_bits,
1071    .pf_packno_bits2len               =  lsquic_gquic_packno_bits2len,
1072    .pf_gen_crypto_frame              =  lsquic_gquic_be_gen_crypto_frame,
1073    .pf_parse_crypto_frame            =  lsquic_gquic_be_parse_crypto_frame,
1074    .pf_packno_info                   =  lsquic_gquic_be_packno_info,
1075    .pf_gen_handshake_done_frame      =  gquic_Q043_gen_handshake_done_frame,
1076    .pf_parse_handshake_done_frame    =  gquic_Q043_parse_handshake_done_frame,
1077    .pf_handshake_done_frame_size     =  gquic_Q043_handshake_done_frame_size,
1078};
1079