lsquic_parse_gquic_be.c revision de46bf2f
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    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 = 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 = 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
487gquic_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
498gquic_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
522gquic_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
541gquic_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
552gquic_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
574gquic_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
590gquic_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
608gquic_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
622gquic_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
631gquic_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
661gquic_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
679gquic_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
691int
692gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
693    int app_error_UNUSED, unsigned ecode, const char *reason, int reason_len)
694{
695    uint32_t error_code;
696    unsigned char *p = buf;
697    if ((int) buf_len < 7 + reason_len)
698        return -1;
699
700    *p = 0x02;
701    ++p;
702    error_code = ecode;
703#if __BYTE_ORDER == __LITTLE_ENDIAN
704    error_code = bswap_32(error_code);
705#endif
706    memcpy(p, &error_code, 4);
707    p += 4;
708#if __BYTE_ORDER == __LITTLE_ENDIAN
709    const uint16_t copy = bswap_16(reason_len);
710    memcpy(p, &copy, 2);
711#else
712    memcpy(p, &reason_len, 2);
713#endif
714    p += 2;
715    memcpy(p, reason, reason_len);
716    p += reason_len;
717
718    return p - buf;
719}
720
721
722int
723gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
724        int *app_error, uint64_t *error_code_p,
725        uint16_t *reason_len, uint8_t *reason_offset)
726{
727    uint32_t error_code;
728
729    if (buf_len < 7)
730        return -1;
731
732    READ_UINT(error_code, 32, buf + 1, 4);
733    READ_UINT(*reason_len, 16, buf + 1 + 4, 2);
734    *reason_offset = 7;
735    if (buf_len < 7u + *reason_len)
736        return -2;
737
738    *error_code_p = error_code;
739    if (app_error)
740        *app_error = 0;
741
742    return 7 + *reason_len;
743}
744
745
746int
747gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len,
748        uint32_t error_code, lsquic_stream_id_t last_good_stream_id64,
749        const char *reason, size_t reason_len)
750{
751    uint32_t last_good_stream_id = last_good_stream_id64;
752    unsigned char *p = buf;
753    if (buf_len < GQUIC_GOAWAY_FRAME_SZ + reason_len)
754        return -1;
755
756    *p = 0x03;
757    ++p;
758#if __BYTE_ORDER == __LITTLE_ENDIAN
759    error_code = bswap_32(error_code);
760#endif
761    memcpy(p, &error_code, 4);
762    p += 4;
763#if __BYTE_ORDER == __LITTLE_ENDIAN
764    last_good_stream_id = bswap_32(last_good_stream_id);
765#endif
766    memcpy(p, &last_good_stream_id, 4);
767    p += 4;
768#if __BYTE_ORDER == __LITTLE_ENDIAN
769    uint16_t copy = bswap_16(reason_len);
770    memcpy(p, &copy, 2);
771#else
772    memcpy(p, &reason_len, 2);
773#endif
774    p += 2;
775    if (reason_len)
776    {
777        memcpy(p, reason, reason_len);
778        p += reason_len;
779    }
780
781    return p - buf;
782}
783
784
785/* the reason is buf + *reason_offset, length is *reason_length */
786int
787gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
788               uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
789               uint16_t *reason_length, const char **reason)
790{
791    uint32_t stream_id;
792    if (buf_len < GQUIC_GOAWAY_FRAME_SZ)
793        return -1;
794
795    READ_UINT(*error_code,          32, buf + 1,         4);
796    READ_UINT(stream_id,            32, buf + 1 + 4,     4);
797    READ_UINT(*reason_length,       16, buf + 1 + 4 + 4, 2);
798    if (*reason_length)
799    {
800        if ((int)buf_len < GQUIC_GOAWAY_FRAME_SZ + *reason_length)
801            return -2;
802        *reason = (const char *) buf + GQUIC_GOAWAY_FRAME_SZ;
803    }
804    else
805        *reason = NULL;
806
807    *last_good_stream_id = stream_id;
808    return GQUIC_GOAWAY_FRAME_SZ + *reason_length;
809}
810
811
812/* Returns number of bytes written or -1 on failure */
813/* This function makes an assumption that there is at least one range */
814int
815gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
816        gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next,
817        gaf_rechist_largest_recv_f rechist_largest_recv,
818        void *rechist, lsquic_time_t now, int *has_missing,
819        lsquic_packno_t *largest_received, const uint64_t *unused)
820{
821    lsquic_time_t time_diff;
822    lsquic_packno_t tmp_packno;
823    const struct lsquic_packno_range *const first = rechist_first(rechist);
824    if (!first)
825    {
826        errno = EINVAL;
827        return -1;
828    }
829
830    /* Copy values from the first range, because the memory the pointer
831     * points to may change:
832     */
833    const lsquic_packno_t first_low = first->low, first_high = first->high;
834
835    unsigned char *p = outbuf;
836    unsigned char *const type = p;
837    unsigned char *const end = p + outbuf_sz;
838
839#define AVAIL() (end - p)
840
841#define CHECKOUT(sz) do {                                               \
842    if ((intptr_t) (sz) > AVAIL()) {                                    \
843        errno = ENOBUFS;                                                \
844        return -1;                                                      \
845    }                                                                   \
846} while (0)
847
848    CHECKOUT(1);
849    ++p;
850
851    /* 01nullmm */
852    *type = 0x40;
853
854    unsigned largest_acked_len, ack_block_len, bits;
855
856    /* Calculate largest ACKed len and set `ll' bits: */
857    const lsquic_packno_t maxno = first_high;
858    bits = (maxno >= (1ULL <<  8))
859         + (maxno >= (1ULL << 16))
860         + (maxno >= (1ULL << 32));
861    largest_acked_len = (1 << bits) - ((maxno >= (1ULL << 32)) << 1);
862    *type |= bits << 2;
863
864    /* Calculate largest ACK block length and set `mm' bits: */
865    unsigned n_ranges = 0;
866    lsquic_packno_t maxdiff = 0;
867    const struct lsquic_packno_range *range;
868    for (range = rechist_first(rechist); range; range = rechist_next(rechist))
869    {
870        ++n_ranges;
871        const lsquic_packno_t diff = range->high - range->low + 1;
872        if (diff > maxdiff)
873            maxdiff = diff;
874    }
875    bits = (maxdiff >= (1ULL <<  8))
876         + (maxdiff >= (1ULL << 16))
877         + (maxdiff >= (1ULL << 32));
878    ack_block_len = (1 << bits) - ((maxdiff >= (1ULL << 32)) << 1);
879    *type |= bits;
880
881    CHECKOUT(largest_acked_len);
882    tmp_packno = maxno;
883#if __BYTE_ORDER == __LITTLE_ENDIAN
884    tmp_packno = bswap_64(maxno);
885#endif
886    memcpy(p, (unsigned char *) &tmp_packno + 8 - largest_acked_len,
887                                                            largest_acked_len);
888    p += largest_acked_len;
889
890    CHECKOUT(2);
891    time_diff = now - rechist_largest_recv(rechist);
892    gquic_be_write_float_time16(time_diff, p);
893    LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff,
894        *(uint16_t*)p);
895    p += 2;
896
897    if (n_ranges > 1)
898    {
899        *has_missing = 1;
900        *type |= 0x20;
901        /* We need to write out at least one range */
902        CHECKOUT(2 * (1 + ack_block_len));
903        unsigned char *const n_ranges_p = p;             /* Set this later */
904        lsquic_packno_t diff = maxno - first_low + 1;
905#if __BYTE_ORDER == __LITTLE_ENDIAN
906        diff = bswap_64(diff);
907#endif
908        memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len,
909                                                            ack_block_len);
910        p += ack_block_len + 1;
911        /* Write out ack blocks until one of the following occurs:
912         *  1. We run out of intervals.
913         *  2. We run out of room.
914         *  3. We run out of highest possible number of ACK blocks (0xFF).
915         */
916        range = rechist_first(rechist);
917        lsquic_packno_t gap = 0;
918        n_ranges = 0;
919        do {
920            if (0 == gap)
921            {
922                const lsquic_packno_t prev_low = range->low;
923                range = rechist_next(rechist);
924                if (!range)
925                    break;
926                gap = prev_low - range->high - 1;
927            }
928            if (gap >= 0x100)
929            {
930                *p = 0xFF;
931                gap -= 0xFF;
932                memset(p + 1, 0, ack_block_len);
933            }
934            else
935            {
936                *p = gap;
937                gap = 0;
938                diff = range->high - range->low + 1;
939#if __BYTE_ORDER == __LITTLE_ENDIAN
940                diff = bswap_64(diff);
941#endif
942                memcpy(p + 1, (unsigned char *) &diff + 8 - ack_block_len,
943                                                                ack_block_len);
944            }
945            p += ack_block_len + 1;
946            ++n_ranges;
947        } while (n_ranges < 0xFF &&
948                 AVAIL() >= (intptr_t) ack_block_len + 1 + 1 /* timestamp byte */);
949        *n_ranges_p = n_ranges;
950    }
951    else
952    {
953        *has_missing = 0;
954        CHECKOUT(ack_block_len);
955        lsquic_packno_t diff = maxno - first_low + 1;
956#if __BYTE_ORDER == __LITTLE_ENDIAN
957        diff = bswap_64(diff);
958#endif
959        memcpy(p, (unsigned char *) &diff + 8 - ack_block_len, ack_block_len);
960        p += ack_block_len;
961    }
962
963    /* We do not generate timestamp list because the reference implementation
964     * does not use them.  When that changes, we will start sending timestamps
965     * over.
966     */
967    CHECKOUT(1);
968    *p = 0;
969    ++p;
970
971    *largest_received = maxno;
972    return p - (unsigned char *) outbuf;
973
974#undef CHECKOUT
975}
976
977
978static int
979gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
980        uint64_t offset, size_t size, gcf_read_f gcf_read, void *stream)
981{
982    assert(0);
983    return -1;
984}
985
986
987static int
988gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
989                                            struct stream_frame *stream_frame)
990{
991    assert(0);
992    return -1;
993}
994
995
996static void
997gquic_be_packno_info (const struct lsquic_conn *lconn,
998        const struct lsquic_packet_out *packet_out, unsigned *packno_off,
999        unsigned *packno_len)
1000{
1001    assert(0);
1002}
1003
1004
1005const struct parse_funcs lsquic_parse_funcs_gquic_Q039 =
1006{
1007    .pf_gen_reg_pkt_header            =  gquic_be_gen_reg_pkt_header,
1008    .pf_parse_packet_in_finish        =  gquic_be_parse_packet_in_finish,
1009    .pf_gen_stream_frame              =  gquic_be_gen_stream_frame,
1010    .pf_calc_stream_frame_header_sz   =  calc_stream_frame_header_sz_gquic,
1011    .pf_parse_stream_frame            =  gquic_be_parse_stream_frame,
1012    .pf_parse_ack_frame               =  gquic_be_parse_ack_frame,
1013    .pf_gen_ack_frame                 =  gquic_be_gen_ack_frame,
1014    .pf_gen_stop_waiting_frame        =  gquic_be_gen_stop_waiting_frame,
1015    .pf_parse_stop_waiting_frame      =  gquic_be_parse_stop_waiting_frame,
1016    .pf_skip_stop_waiting_frame       =  gquic_be_skip_stop_waiting_frame,
1017    .pf_gen_window_update_frame       =  gquic_be_gen_window_update_frame,
1018    .pf_parse_window_update_frame     =  gquic_be_parse_window_update_frame,
1019    .pf_gen_blocked_frame             =  gquic_be_gen_blocked_frame,
1020    .pf_parse_blocked_frame           =  gquic_be_parse_blocked_frame,
1021    .pf_rst_frame_size                =  gquic_be_rst_frame_size,
1022    .pf_gen_rst_frame                 =  gquic_be_gen_rst_frame,
1023    .pf_parse_rst_frame               =  gquic_be_parse_rst_frame,
1024    .pf_gen_connect_close_frame       =  gquic_be_gen_connect_close_frame,
1025    .pf_parse_connect_close_frame     =  gquic_be_parse_connect_close_frame,
1026    .pf_gen_goaway_frame              =  gquic_be_gen_goaway_frame,
1027    .pf_parse_goaway_frame            =  gquic_be_parse_goaway_frame,
1028    .pf_gen_ping_frame                =  gquic_be_gen_ping_frame,
1029#ifndef NDEBUG
1030    .pf_write_float_time16            =  gquic_be_write_float_time16,
1031    .pf_read_float_time16             =  gquic_be_read_float_time16,
1032#endif
1033    .pf_generate_simple_prst          =  lsquic_generate_gquic_reset,
1034    .pf_parse_frame_type              =  lsquic_parse_frame_type_gquic_Q035_thru_Q046,
1035    .pf_turn_on_fin                   =  lsquic_turn_on_fin_Q035_thru_Q046,
1036    .pf_packout_size                  =  lsquic_gquic_packout_size,
1037    .pf_packout_max_header_size       =  lsquic_gquic_packout_header_size,
1038    .pf_calc_packno_bits              =  lsquic_gquic_calc_packno_bits,
1039    .pf_packno_bits2len               =  lsquic_gquic_packno_bits2len,
1040    .pf_gen_crypto_frame              =  gquic_be_gen_crypto_frame,
1041    .pf_parse_crypto_frame            =  gquic_be_parse_crypto_frame,
1042    .pf_packno_info                   =  gquic_be_packno_info,
1043};
1044