• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ngtcp2_get_uint64(const uint8_t * p)34 uint64_t ngtcp2_get_uint64(const uint8_t *p) {
35   uint64_t n;
36   memcpy(&n, p, 8);
37   return ngtcp2_ntohl64(n);
38 }
39 
ngtcp2_get_uint48(const uint8_t * p)40 uint64_t ngtcp2_get_uint48(const uint8_t *p) {
41   uint64_t n = 0;
42   memcpy(((uint8_t *)&n) + 2, p, 6);
43   return ngtcp2_ntohl64(n);
44 }
45 
ngtcp2_get_uint32(const uint8_t * p)46 uint32_t ngtcp2_get_uint32(const uint8_t *p) {
47   uint32_t n;
48   memcpy(&n, p, 4);
49   return ngtcp2_ntohl(n);
50 }
51 
ngtcp2_get_uint24(const uint8_t * p)52 uint32_t ngtcp2_get_uint24(const uint8_t *p) {
53   uint32_t n = 0;
54   memcpy(((uint8_t *)&n) + 1, p, 3);
55   return ngtcp2_ntohl(n);
56 }
57 
ngtcp2_get_uint16(const uint8_t * p)58 uint16_t ngtcp2_get_uint16(const uint8_t *p) {
59   uint16_t n;
60   memcpy(&n, p, 2);
61   return ngtcp2_ntohs(n);
62 }
63 
ngtcp2_get_varint(size_t * plen,const uint8_t * p)64 uint64_t ngtcp2_get_varint(size_t *plen, const uint8_t *p) {
65   union {
66     char b[8];
67     uint16_t n16;
68     uint32_t n32;
69     uint64_t n64;
70   } n;
71 
72   *plen = (size_t)(1u << (*p >> 6));
73 
74   switch (*plen) {
75   case 1:
76     return *p;
77   case 2:
78     memcpy(&n, p, 2);
79     n.b[0] &= 0x3f;
80     return ngtcp2_ntohs(n.n16);
81   case 4:
82     memcpy(&n, p, 4);
83     n.b[0] &= 0x3f;
84     return ngtcp2_ntohl(n.n32);
85   case 8:
86     memcpy(&n, p, 8);
87     n.b[0] &= 0x3f;
88     return ngtcp2_ntohl64(n.n64);
89   default:
90     assert(0);
91   }
92 
93   return 0;
94 }
95 
ngtcp2_get_pkt_num(const uint8_t * p,size_t pkt_numlen)96 int64_t ngtcp2_get_pkt_num(const uint8_t *p, size_t pkt_numlen) {
97   switch (pkt_numlen) {
98   case 1:
99     return *p;
100   case 2:
101     return (int64_t)ngtcp2_get_uint16(p);
102   case 3:
103     return (int64_t)ngtcp2_get_uint24(p);
104   case 4:
105     return (int64_t)ngtcp2_get_uint32(p);
106   default:
107     assert(0);
108     abort();
109   }
110 }
111 
ngtcp2_put_uint64be(uint8_t * p,uint64_t n)112 uint8_t *ngtcp2_put_uint64be(uint8_t *p, uint64_t n) {
113   n = ngtcp2_htonl64(n);
114   return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n));
115 }
116 
ngtcp2_put_uint48be(uint8_t * p,uint64_t n)117 uint8_t *ngtcp2_put_uint48be(uint8_t *p, uint64_t n) {
118   n = ngtcp2_htonl64(n);
119   return ngtcp2_cpymem(p, ((const uint8_t *)&n) + 2, 6);
120 }
121 
ngtcp2_put_uint32be(uint8_t * p,uint32_t n)122 uint8_t *ngtcp2_put_uint32be(uint8_t *p, uint32_t n) {
123   n = ngtcp2_htonl(n);
124   return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n));
125 }
126 
ngtcp2_put_uint24be(uint8_t * p,uint32_t n)127 uint8_t *ngtcp2_put_uint24be(uint8_t *p, uint32_t n) {
128   n = ngtcp2_htonl(n);
129   return ngtcp2_cpymem(p, ((const uint8_t *)&n) + 1, 3);
130 }
131 
ngtcp2_put_uint16be(uint8_t * p,uint16_t n)132 uint8_t *ngtcp2_put_uint16be(uint8_t *p, uint16_t n) {
133   n = ngtcp2_htons(n);
134   return ngtcp2_cpymem(p, (const uint8_t *)&n, sizeof(n));
135 }
136 
ngtcp2_put_varint(uint8_t * p,uint64_t n)137 uint8_t *ngtcp2_put_varint(uint8_t *p, uint64_t n) {
138   uint8_t *rv;
139   if (n < 64) {
140     *p++ = (uint8_t)n;
141     return p;
142   }
143   if (n < 16384) {
144     rv = ngtcp2_put_uint16be(p, (uint16_t)n);
145     *p |= 0x40;
146     return rv;
147   }
148   if (n < 1073741824) {
149     rv = ngtcp2_put_uint32be(p, (uint32_t)n);
150     *p |= 0x80;
151     return rv;
152   }
153   assert(n < 4611686018427387904ULL);
154   rv = ngtcp2_put_uint64be(p, n);
155   *p |= 0xc0;
156   return rv;
157 }
158 
ngtcp2_put_varint30(uint8_t * p,uint32_t n)159 uint8_t *ngtcp2_put_varint30(uint8_t *p, uint32_t n) {
160   uint8_t *rv;
161 
162   assert(n < 1073741824);
163 
164   rv = ngtcp2_put_uint32be(p, n);
165   *p |= 0x80;
166 
167   return rv;
168 }
169 
ngtcp2_put_pkt_num(uint8_t * p,int64_t pkt_num,size_t len)170 uint8_t *ngtcp2_put_pkt_num(uint8_t *p, int64_t pkt_num, size_t len) {
171   switch (len) {
172   case 1:
173     *p++ = (uint8_t)pkt_num;
174     return p;
175   case 2:
176     ngtcp2_put_uint16be(p, (uint16_t)pkt_num);
177     return p + 2;
178   case 3:
179     ngtcp2_put_uint24be(p, (uint32_t)pkt_num);
180     return p + 3;
181   case 4:
182     ngtcp2_put_uint32be(p, (uint32_t)pkt_num);
183     return p + 4;
184   default:
185     assert(0);
186     abort();
187   }
188 }
189 
ngtcp2_get_varint_len(const uint8_t * p)190 size_t ngtcp2_get_varint_len(const uint8_t *p) {
191   return (size_t)(1u << (*p >> 6));
192 }
193 
ngtcp2_put_varint_len(uint64_t n)194 size_t ngtcp2_put_varint_len(uint64_t n) {
195   if (n < 64) {
196     return 1;
197   }
198   if (n < 16384) {
199     return 2;
200   }
201   if (n < 1073741824) {
202     return 4;
203   }
204   assert(n < 4611686018427387904ULL);
205   return 8;
206 }
207 
ngtcp2_nth_server_bidi_id(uint64_t n)208 int64_t ngtcp2_nth_server_bidi_id(uint64_t n) {
209   if (n == 0) {
210     return 0;
211   }
212 
213   if ((NGTCP2_MAX_VARINT >> 2) < n - 1) {
214     return NGTCP2_MAX_SERVER_STREAM_ID_BIDI;
215   }
216 
217   return (int64_t)(((n - 1) << 2) | 0x01);
218 }
219 
ngtcp2_nth_client_bidi_id(uint64_t n)220 int64_t ngtcp2_nth_client_bidi_id(uint64_t n) {
221   if (n == 0) {
222     return 0;
223   }
224 
225   if ((NGTCP2_MAX_VARINT >> 2) < n - 1) {
226     return NGTCP2_MAX_CLIENT_STREAM_ID_BIDI;
227   }
228 
229   return (int64_t)((n - 1) << 2);
230 }
231 
ngtcp2_nth_server_uni_id(uint64_t n)232 int64_t ngtcp2_nth_server_uni_id(uint64_t n) {
233   if (n == 0) {
234     return 0;
235   }
236 
237   if ((NGTCP2_MAX_VARINT >> 2) < n - 1) {
238     return NGTCP2_MAX_SERVER_STREAM_ID_UNI;
239   }
240 
241   return (int64_t)(((n - 1) << 2) | 0x03);
242 }
243 
ngtcp2_nth_client_uni_id(uint64_t n)244 int64_t ngtcp2_nth_client_uni_id(uint64_t n) {
245   if (n == 0) {
246     return 0;
247   }
248 
249   if ((NGTCP2_MAX_VARINT >> 2) < n - 1) {
250     return NGTCP2_MAX_CLIENT_STREAM_ID_UNI;
251   }
252 
253   return (int64_t)(((n - 1) << 2) | 0x02);
254 }
255 
ngtcp2_ord_stream_id(int64_t stream_id)256 uint64_t ngtcp2_ord_stream_id(int64_t stream_id) {
257   return (uint64_t)(stream_id >> 2) + 1;
258 }
259