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