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