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