summaryrefslogtreecommitdiff
path: root/include/internal/packet_quic.h
blob: 447f75b81f315c82809afd60a96f66598d799308 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#ifndef OSSL_INTERNAL_PACKET_QUIC_H
# define OSSL_INTERNAL_PACKET_QUIC_H
# pragma once

# include "internal/packet.h"
# include "internal/quic_vlint.h"

# ifndef OPENSSL_NO_QUIC
/*
 * Decodes a QUIC variable-length integer in |pkt| and stores the result in
 * |data|.
 */
__owur static ossl_inline int PACKET_get_quic_vlint(PACKET *pkt,
                                                    uint64_t *data)
{
    size_t enclen;

    if (PACKET_remaining(pkt) < 1)
        return 0;

    enclen = ossl_quic_vlint_decode_len(*pkt->curr);

    if (PACKET_remaining(pkt) < enclen)
        return 0;

    *data = ossl_quic_vlint_decode_unchecked(pkt->curr);
    packet_forward(pkt, enclen);
    return 1;
}

/*
 * Decodes a QUIC variable-length integer in |pkt| and stores the result in
 * |data|. Unlike PACKET_get_quic_vlint, this does not advance the current
 * position.
 */
__owur static ossl_inline int PACKET_peek_quic_vlint(PACKET *pkt,
                                                     uint64_t *data)
{
    size_t enclen;

    if (PACKET_remaining(pkt) < 1)
        return 0;

    enclen = ossl_quic_vlint_decode_len(*pkt->curr);

    if (PACKET_remaining(pkt) < enclen)
        return 0;

    *data = ossl_quic_vlint_decode_unchecked(pkt->curr);
    return 1;
}

/*
 * Skips over a QUIC variable-length integer in |pkt| without decoding it.
 */
__owur static ossl_inline int PACKET_skip_quic_vlint(PACKET *pkt)
{
    size_t enclen;

    if (PACKET_remaining(pkt) < 1)
        return 0;

    enclen = ossl_quic_vlint_decode_len(*pkt->curr);

    if (PACKET_remaining(pkt) < enclen)
        return 0;

    packet_forward(pkt, enclen);
    return 1;
}

/*
 * Reads a variable-length vector prefixed with a QUIC variable-length integer
 * denoting the length, and stores the contents in |subpkt|. |pkt| can equal
 * |subpkt|. Data is not copied: the |subpkt| packet will share its underlying
 * buffer with the original |pkt|, so data wrapped by |pkt| must outlive the
 * |subpkt|. Upon failure, the original |pkt| and |subpkt| are not modified.
 */
__owur static ossl_inline int PACKET_get_quic_length_prefixed(PACKET *pkt,
                                                              PACKET *subpkt)
{
    uint64_t length;
    const unsigned char *data;
    PACKET tmp = *pkt;

    if (!PACKET_get_quic_vlint(&tmp, &length) ||
        length > SIZE_MAX ||
        !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
        return 0;
    }

    *pkt = tmp;
    subpkt->curr = data;
    subpkt->remaining = (size_t)length;

    return 1;
}

/*
 * Starts a QUIC sub-packet headed by a QUIC variable-length integer. A 4-byte
 * representation is used.
 */
__owur int WPACKET_start_quic_sub_packet(WPACKET *pkt);

/*
 * Starts a QUIC sub-packet headed by a QUIC variable-length integer. max_len
 * specifies the upper bound for the sub-packet size at the time the sub-packet
 * is closed, which determines the encoding size for tthe variable-length
 * integer header. max_len can be a precise figure or a worst-case bound
 * if a precise figure is not available.
 */
__owur int WPACKET_start_quic_sub_packet_bound(WPACKET *pkt, size_t max_len);

/*
 * Allocates a QUIC sub-packet with exactly len bytes of payload, headed by a
 * QUIC variable-length integer. The pointer to the payload buffer is output and
 * must be filled by the caller. This function assures optimal selection of
 * variable-length integer encoding length.
 */
__owur int WPACKET_quic_sub_allocate_bytes(WPACKET *pkt, size_t len,
                                           unsigned char **bytes);

/*
 * Write a QUIC variable-length integer to the packet.
 */
__owur int WPACKET_quic_write_vlint(WPACKET *pkt, uint64_t v);

# endif                         /* OPENSSL_NO_QUIC */
#endif                          /* OSSL_INTERNAL_PACKET_QUIC_H */