1 #include "config.h"
2 #include <ccan/asort/asort.h>
3 #include <common/bigsize.h>
4 #include <wire/tlvstream.h>
5 #include <wire/wire.h>
6 
7 #ifndef SUPERVERBOSE
8 #define SUPERVERBOSE(...)
9 #endif
10 
tlv_field_cmp(const struct tlv_field * a,const struct tlv_field * b,void * x)11 static int tlv_field_cmp(const struct tlv_field *a, const struct tlv_field *b,
12 			 void *x)
13 {
14 	return a->numtype > b->numtype ? 1 : -1;
15 }
16 
towire_tlvstream_raw(u8 ** pptr,struct tlv_field * fields)17 void towire_tlvstream_raw(u8 **pptr, struct tlv_field *fields)
18 {
19 	if (!fields)
20 		return;
21 
22 	asort(fields, tal_count(fields), tlv_field_cmp, NULL);
23 
24 	for (size_t i = 0; i < tal_count(fields); i++) {
25 		const struct tlv_field *field = &fields[i];
26 		/* BOLT #1:
27 		 *
28 		 * The sending node:
29 		 ...
30 		 *  - MUST minimally encode `type` and `length`.
31 		 */
32 		towire_bigsize(pptr, field->numtype);
33 		towire_bigsize(pptr, field->length);
34 		towire(pptr, field->value, field->length);
35 	}
36 }
37 
tlvstream_get_raw(struct tlv_field * stream,u64 type)38 static struct tlv_field *tlvstream_get_raw(struct tlv_field *stream, u64 type)
39 {
40 	for (size_t i=0; i<tal_count(stream); i++)
41 		if (stream[i].numtype == type)
42 			return &stream[i];
43 	return NULL;
44 }
45 
tlvstream_set_raw(struct tlv_field ** stream,u64 type,void * value TAKES,size_t valuelen)46 void tlvstream_set_raw(struct tlv_field **stream, u64 type, void *value TAKES, size_t valuelen)
47 {
48 	struct tlv_field f, *e = tlvstream_get_raw(*stream, type);
49 
50 	if (e != NULL) {
51 		tal_free(e->value);
52 		e->length = valuelen;
53 		e->value = tal_dup_arr(*stream, u8, value, e->length, 0);
54 	} else {
55 		/* If we haven't found it insert it insead. */
56 		f.length = valuelen;
57 		f.numtype = type;
58 		f.value = tal_dup_arr(*stream, u8, value, f.length, 0);
59 		tal_arr_expand(stream, f);
60 	}
61 }
62 
tlvstream_set_short_channel_id(struct tlv_field ** stream,u64 type,struct short_channel_id * value)63 void tlvstream_set_short_channel_id(struct tlv_field **stream, u64 type,
64 				    struct short_channel_id *value)
65 {
66 	u8 *ser = tal_arr(NULL, u8, 0);
67 	towire_short_channel_id(&ser, value);
68 	tlvstream_set_raw(stream, type, take(ser), tal_bytelen(ser));
69 }
70 
tlvstream_set_tu64(struct tlv_field ** stream,u64 type,u64 value)71 void tlvstream_set_tu64(struct tlv_field **stream, u64 type, u64 value)
72 {
73 	u8 *ser = tal_arr(NULL, u8, 0);
74 	towire_tu64(&ser, value);
75 	tlvstream_set_raw(stream, type, take(ser), tal_bytelen(ser));
76 }
77 
tlvstream_set_tu32(struct tlv_field ** stream,u64 type,u32 value)78 void tlvstream_set_tu32(struct tlv_field **stream, u64 type, u32 value)
79 {
80 	u8 *ser = tal_arr(NULL, u8, 0);
81 	towire_tu64(&ser, value);
82 	tlvstream_set_raw(stream, type, take(ser), tal_bytelen(ser));
83 }
84 
tlvstream_get_short_channel_id(struct tlv_field * stream,u64 type,struct short_channel_id * value)85 bool tlvstream_get_short_channel_id(struct tlv_field *stream, u64 type,
86 				    struct short_channel_id *value)
87 {
88 	struct tlv_field *raw = tlvstream_get_raw(stream, type);
89 	const u8 *v;
90 	size_t max;
91 	if (raw == NULL || raw->length != 8)
92 		return false;
93 
94 	max = raw->length;
95 	v = raw->value;
96 	fromwire_short_channel_id(&v, &max, value);
97 
98 	return true;
99 }
100 
tlvstream_get_tu64(struct tlv_field * stream,u64 type,u64 * value)101 bool tlvstream_get_tu64(struct tlv_field *stream, u64 type, u64 *value)
102 {
103 	struct tlv_field *raw = tlvstream_get_raw(stream, type);
104 	const u8 *v;
105 	size_t max;
106 	if (raw == NULL || raw->length != 8)
107 		return false;
108 
109 	max = raw->length;
110 	v = raw->value;
111 	*value = fromwire_tu64(&v, &max);
112 
113 	return true;
114 }
115 
tlvstream_get_tu32(struct tlv_field * stream,u64 type,u32 * value)116 bool tlvstream_get_tu32(struct tlv_field *stream, u64 type, u32 *value)
117 {
118 	struct tlv_field *raw = tlvstream_get_raw(stream, type);
119 	const u8 *v;
120 	size_t max;
121 	if (raw == NULL || raw->length != 8)
122 		return false;
123 
124 	max = raw->length;
125 	v = raw->value;
126 	*value = fromwire_tu64(&v, &max);
127 	return true;
128 }
129 
fromwire_tlv(const u8 ** cursor,size_t * max,const struct tlv_record_type * types,size_t num_types,void * record,struct tlv_field ** fields)130 bool fromwire_tlv(const u8 **cursor, size_t *max,
131 		  const struct tlv_record_type *types, size_t num_types,
132 		  void *record, struct tlv_field **fields)
133 {
134 	while (*max > 0) {
135 		struct tlv_field field;
136 
137 		/* BOLT #1:
138 		 *
139 		 * The `type` is encoded using the BigSize format.
140 		 */
141 		field.numtype = fromwire_bigsize(cursor, max);
142 
143 		/* BOLT #1:
144 		 *  - if a `type` or `length` is not minimally encoded:
145 		 *    - MUST fail to parse the `tlv_stream`.
146 		 */
147 		if (!*cursor) {
148 			SUPERVERBOSE("type");
149 			goto fail;
150 		}
151 		field.length = fromwire_bigsize(cursor, max);
152 
153 		/* BOLT #1:
154 		 *  - if a `type` or `length` is not minimally encoded:
155 		 *    - MUST fail to parse the `tlv_stream`.
156 		 */
157 		if (!*cursor) {
158 			SUPERVERBOSE("length");
159 			goto fail;
160 		}
161 
162 		/* BOLT #1:
163 		 *  - if `length` exceeds the number of bytes remaining in the
164 		 *    message:
165 		 *    - MUST fail to parse the `tlv_stream`.
166 		 */
167 		if (field.length > *max) {
168 			SUPERVERBOSE("value");
169 			goto fail;
170 		}
171 		field.value = tal_dup_arr(record, u8, *cursor, field.length, 0);
172 
173 		/* BOLT #1:
174 		 * - if `type` is known:
175 		 *   - MUST decode the next `length` bytes using the known
176 		 *     encoding for `type`.
177 		 */
178 		field.meta = NULL;
179 		for (size_t i = 0; i < num_types; i++) {
180 			if (types[i].type == field.numtype)
181 				field.meta = &types[i];
182 		}
183 
184 		if (field.meta) {
185 			/* Length of message can't exceed 16 bits anyway. */
186 			size_t tlvlen = field.length;
187 			field.meta->fromwire(cursor, &tlvlen, record);
188 
189 			if (!*cursor)
190 				goto fail;
191 
192 			/* BOLT #1:
193 			 *  - if `length` is not exactly equal to that required
194 			 *    for the known encoding for `type`:
195 			 *    - MUST fail to parse the `tlv_stream`.
196 			 */
197 			if (tlvlen != 0) {
198 				SUPERVERBOSE("greater than encoding length");
199 				goto fail;
200 			}
201 		} else {
202 			/* We didn't read from *cursor through a fromwire, so
203 			 * update manually. */
204 			*cursor += field.length;
205 		}
206 		/* We've read bytes in ->fromwire, so update max */
207 		*max -= field.length;
208 		tal_arr_expand(fields, field);
209 	}
210 	return true;
211 fail:
212 	fromwire_fail(cursor, max);
213 	return false;
214 }
215 
tlv_type_is_allowed(const struct tlv_field * f,u64 * extra_types)216 static bool tlv_type_is_allowed(const struct tlv_field *f, u64 *extra_types) {
217 	/* Simple case: we have internal meta fields or it's an odd field. */
218 	if (f->numtype % 2 != 0 || f->meta != NULL)
219 		return true;
220 
221 	if (extra_types == NULL)
222 		return false;
223 
224 	/* Now iterate through the extras and see if we should make an
225 	 * exception. */
226 	for (size_t i = 0; i < tal_count(extra_types); i++)
227 		if (extra_types[i] == f->numtype)
228 			return true;
229 	return false;
230 }
231 
tlv_fields_valid(const struct tlv_field * fields,u64 * allow_extra,size_t * err_index)232 bool tlv_fields_valid(const struct tlv_field *fields, u64 *allow_extra,
233 		      size_t *err_index)
234 {
235 	size_t numfields = tal_count(fields);
236 	bool first = true;
237 	u64 prev_type = 0;
238 	for (int i=0; i<numfields; i++) {
239 		const struct tlv_field *f = &fields[i];
240 		if (!tlv_type_is_allowed(f, allow_extra)) {
241 			/* BOLT #1:
242 			 * - otherwise, if `type` is unknown:
243 			 *   - if `type` is even:
244 			 *     - MUST fail to parse the `tlv_stream`.
245 			 *   - otherwise, if `type` is odd:
246 			 *     - MUST discard the next `length` bytes.
247 			 */
248 			SUPERVERBOSE("unknown even");
249 			if (err_index != NULL)
250 				*err_index = i;
251 			return false;
252 		} else if (!first && f->numtype <= prev_type) {
253 			/* BOLT #1:
254 			 *  - if decoded `type`s are not strictly-increasing
255 			 *    (including situations when two or more occurrences
256 			 *    of the same `type` are met):
257 			 *    - MUST fail to parse the `tlv_stream`.
258 			 */
259 			if (f->numtype == prev_type)
260 				SUPERVERBOSE("duplicate tlv type");
261 			else
262 				SUPERVERBOSE("invalid ordering");
263 			if (err_index != NULL)
264 				*err_index = i;
265 			return false;
266 		}
267 		first = false;
268 		prev_type = f->numtype;
269 	}
270 	return true;
271 }
272 
towire_tlv(u8 ** pptr,const struct tlv_record_type * types,size_t num_types,const void * record)273 void towire_tlv(u8 **pptr,
274 		const struct tlv_record_type *types, size_t num_types,
275 		const void *record)
276 {
277 	if (!record)
278 		return;
279 
280 	for (size_t i = 0; i < num_types; i++) {
281 		u8 *val;
282 		if (i != 0)
283 			assert(types[i].type > types[i-1].type);
284 		val = types[i].towire(NULL, record);
285 		if (!val)
286 			continue;
287 
288 		/* BOLT #1:
289 		 *
290 		 * The sending node:
291 		 ...
292 		 *  - MUST minimally encode `type` and `length`.
293 		 */
294 		towire_bigsize(pptr, types[i].type);
295 		towire_bigsize(pptr, tal_bytelen(val));
296 		towire(pptr, val, tal_bytelen(val));
297 		tal_free(val);
298 	}
299 }
300 
tlv_make_fields_(const struct tlv_record_type * types,size_t num_types,const void * record)301 struct tlv_field *tlv_make_fields_(const struct tlv_record_type *types,
302 				   size_t num_types,
303 				   const void *record)
304 {
305 	struct tlv_field *fields = tal_arr(record, struct tlv_field, 0);
306 
307 	for (size_t i = 0; i < num_types; i++) {
308 		struct tlv_field f;
309 		u8 *val;
310 		if (i != 0)
311 			assert(types[i].type > types[i-1].type);
312 		val = types[i].towire(NULL, record);
313 		if (!val)
314 			continue;
315 
316 		f.meta = &types[i];
317 		f.numtype = types[i].type;
318 		f.length = tal_bytelen(val);
319 		f.value = tal_steal(fields, val);
320 		tal_arr_expand(&fields, f);
321 	}
322 	return fields;
323 }
324