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