/src/samba/third_party/ngtcp2/lib/ngtcp2_conv.c
Line | Count | Source |
1 | | /* |
2 | | * ngtcp2 |
3 | | * |
4 | | * Copyright (c) 2017 ngtcp2 contributors |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining |
7 | | * a copy of this software and associated documentation files (the |
8 | | * "Software"), to deal in the Software without restriction, including |
9 | | * without limitation the rights to use, copy, modify, merge, publish, |
10 | | * distribute, sublicense, and/or sell copies of the Software, and to |
11 | | * permit persons to whom the Software is furnished to do so, subject to |
12 | | * the following conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be |
15 | | * included in all copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
18 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
19 | | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
20 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
21 | | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
22 | | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
23 | | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | | */ |
25 | | #include "ngtcp2_conv.h" |
26 | | |
27 | | #include <string.h> |
28 | | #include <assert.h> |
29 | | |
30 | | #include "ngtcp2_str.h" |
31 | | #include "ngtcp2_pkt.h" |
32 | | #include "ngtcp2_net.h" |
33 | | #include "ngtcp2_unreachable.h" |
34 | | |
35 | 0 | const uint8_t *ngtcp2_get_uint64be(uint64_t *dest, const uint8_t *p) { |
36 | 0 | memcpy(dest, p, sizeof(*dest)); |
37 | 0 | *dest = ngtcp2_ntohl64(*dest); |
38 | 0 | return p + sizeof(*dest); |
39 | 0 | } |
40 | | |
41 | 0 | const uint8_t *ngtcp2_get_uint32be(uint32_t *dest, const uint8_t *p) { |
42 | 0 | memcpy(dest, p, sizeof(*dest)); |
43 | 0 | *dest = ngtcp2_ntohl(*dest); |
44 | 0 | return p + sizeof(*dest); |
45 | 0 | } |
46 | | |
47 | 0 | const uint8_t *ngtcp2_get_uint24be(uint32_t *dest, const uint8_t *p) { |
48 | 0 | *dest = 0; |
49 | 0 | memcpy(((uint8_t *)dest) + 1, p, 3); |
50 | 0 | *dest = ngtcp2_ntohl(*dest); |
51 | 0 | return p + 3; |
52 | 0 | } |
53 | | |
54 | 0 | const uint8_t *ngtcp2_get_uint16be(uint16_t *dest, const uint8_t *p) { |
55 | 0 | memcpy(dest, p, sizeof(*dest)); |
56 | 0 | *dest = ngtcp2_ntohs(*dest); |
57 | 0 | return p + sizeof(*dest); |
58 | 0 | } |
59 | | |
60 | 0 | const uint8_t *ngtcp2_get_uint16(uint16_t *dest, const uint8_t *p) { |
61 | 0 | memcpy(dest, p, sizeof(*dest)); |
62 | 0 | return p + sizeof(*dest); |
63 | 0 | } |
64 | | |
65 | 0 | static const uint8_t *get_uvarint(uint64_t *dest, const uint8_t *p) { |
66 | 0 | uint16_t n16; |
67 | 0 | uint32_t n32; |
68 | 0 | uint64_t n64; |
69 | |
|
70 | 0 | switch (*p >> 6) { |
71 | 0 | case 0: |
72 | 0 | *dest = *p++; |
73 | 0 | return p; |
74 | 0 | case 1: |
75 | 0 | memcpy(&n16, p, 2); |
76 | 0 | n16 = ngtcp2_ntohs(n16); |
77 | 0 | n16 &= 0x3FFF; |
78 | 0 | *dest = n16; |
79 | |
|
80 | 0 | return p + 2; |
81 | 0 | case 2: |
82 | 0 | memcpy(&n32, p, 4); |
83 | 0 | n32 = ngtcp2_ntohl(n32); |
84 | 0 | n32 &= 0x3FFFFFFF; |
85 | 0 | *dest = n32; |
86 | |
|
87 | 0 | return p + 4; |
88 | 0 | case 3: |
89 | 0 | memcpy(&n64, p, 8); |
90 | 0 | n64 = ngtcp2_ntohl64(n64); |
91 | 0 | n64 &= 0x3FFFFFFFFFFFFFFF; |
92 | 0 | *dest = n64; |
93 | |
|
94 | 0 | return p + 8; |
95 | 0 | default: |
96 | 0 | ngtcp2_unreachable(); |
97 | 0 | } |
98 | 0 | } |
99 | | |
100 | 0 | const uint8_t *ngtcp2_get_uvarint(uint64_t *dest, const uint8_t *p) { |
101 | 0 | return get_uvarint(dest, p); |
102 | 0 | } |
103 | | |
104 | 0 | const uint8_t *ngtcp2_get_varint(int64_t *dest, const uint8_t *p) { |
105 | 0 | return get_uvarint((uint64_t *)dest, p); |
106 | 0 | } |
107 | | |
108 | 0 | int64_t ngtcp2_get_pkt_num(const uint8_t *p, size_t pkt_numlen) { |
109 | 0 | uint32_t l; |
110 | 0 | uint16_t s; |
111 | |
|
112 | 0 | switch (pkt_numlen) { |
113 | 0 | case 1: |
114 | 0 | return *p; |
115 | 0 | case 2: |
116 | 0 | ngtcp2_get_uint16be(&s, p); |
117 | 0 | return (int64_t)s; |
118 | 0 | case 3: |
119 | 0 | ngtcp2_get_uint24be(&l, p); |
120 | 0 | return (int64_t)l; |
121 | 0 | case 4: |
122 | 0 | ngtcp2_get_uint32be(&l, p); |
123 | 0 | return (int64_t)l; |
124 | 0 | default: |
125 | 0 | ngtcp2_unreachable(); |
126 | 0 | } |
127 | 0 | } |
128 | | |
129 | 0 | uint8_t *ngtcp2_put_uint64be(uint8_t *p, uint64_t n) { |
130 | 0 | n = ngtcp2_htonl64(n); |
131 | 0 | return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n)); |
132 | 0 | } |
133 | | |
134 | 0 | uint8_t *ngtcp2_put_uint32be(uint8_t *p, uint32_t n) { |
135 | 0 | n = ngtcp2_htonl(n); |
136 | 0 | return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n)); |
137 | 0 | } |
138 | | |
139 | 0 | uint8_t *ngtcp2_put_uint24be(uint8_t *p, uint32_t n) { |
140 | 0 | n = ngtcp2_htonl(n); |
141 | 0 | return ngtcp2_cpymem(p, ((const uint8_t *)&n) + 1, 3); |
142 | 0 | } |
143 | | |
144 | 0 | uint8_t *ngtcp2_put_uint16be(uint8_t *p, uint16_t n) { |
145 | 0 | n = ngtcp2_htons(n); |
146 | 0 | return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n)); |
147 | 0 | } |
148 | | |
149 | 0 | uint8_t *ngtcp2_put_uint16(uint8_t *p, uint16_t n) { |
150 | 0 | return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n)); |
151 | 0 | } |
152 | | |
153 | 0 | uint8_t *ngtcp2_put_uvarint(uint8_t *p, uint64_t n) { |
154 | 0 | uint8_t *rv; |
155 | 0 | if (n < 64) { |
156 | 0 | *p++ = (uint8_t)n; |
157 | 0 | return p; |
158 | 0 | } |
159 | 0 | if (n < 16384) { |
160 | 0 | rv = ngtcp2_put_uint16be(p, (uint16_t)n); |
161 | 0 | *p |= 0x40; |
162 | 0 | return rv; |
163 | 0 | } |
164 | 0 | if (n < 1073741824) { |
165 | 0 | rv = ngtcp2_put_uint32be(p, (uint32_t)n); |
166 | 0 | *p |= 0x80; |
167 | 0 | return rv; |
168 | 0 | } |
169 | 0 | assert(n < 4611686018427387904ULL); |
170 | 0 | rv = ngtcp2_put_uint64be(p, n); |
171 | 0 | *p |= 0xC0; |
172 | 0 | return rv; |
173 | 0 | } |
174 | | |
175 | 0 | uint8_t *ngtcp2_put_uvarint30(uint8_t *p, uint32_t n) { |
176 | 0 | uint8_t *rv; |
177 | |
|
178 | 0 | assert(n < 1073741824); |
179 | |
|
180 | 0 | rv = ngtcp2_put_uint32be(p, n); |
181 | 0 | *p |= 0x80; |
182 | |
|
183 | 0 | return rv; |
184 | 0 | } |
185 | | |
186 | 0 | uint8_t *ngtcp2_put_pkt_num(uint8_t *p, int64_t pkt_num, size_t len) { |
187 | 0 | switch (len) { |
188 | 0 | case 1: |
189 | 0 | *p++ = (uint8_t)pkt_num; |
190 | 0 | return p; |
191 | 0 | case 2: |
192 | 0 | return ngtcp2_put_uint16be(p, (uint16_t)pkt_num); |
193 | 0 | case 3: |
194 | 0 | return ngtcp2_put_uint24be(p, (uint32_t)pkt_num); |
195 | 0 | case 4: |
196 | 0 | return ngtcp2_put_uint32be(p, (uint32_t)pkt_num); |
197 | 0 | default: |
198 | 0 | ngtcp2_unreachable(); |
199 | 0 | } |
200 | 0 | } |
201 | | |
202 | 0 | size_t ngtcp2_get_uvarintlen(const uint8_t *p) { |
203 | 0 | return (size_t)(1U << (*p >> 6)); |
204 | 0 | } |
205 | | |
206 | 0 | size_t ngtcp2_put_uvarintlen(uint64_t n) { |
207 | 0 | if (n < 64) { |
208 | 0 | return 1; |
209 | 0 | } |
210 | 0 | if (n < 16384) { |
211 | 0 | return 2; |
212 | 0 | } |
213 | 0 | if (n < 1073741824) { |
214 | 0 | return 4; |
215 | 0 | } |
216 | 0 | assert(n < 4611686018427387904ULL); |
217 | 0 | return 8; |
218 | 0 | } |
219 | | |
220 | 0 | uint64_t ngtcp2_ord_stream_id(int64_t stream_id) { |
221 | 0 | return (uint64_t)(stream_id >> 2) + 1; |
222 | 0 | } |