diff options
Diffstat (limited to 'src/util/dnsparser.c')
-rw-r--r-- | src/util/dnsparser.c | 1219 |
1 files changed, 610 insertions, 609 deletions
diff --git a/src/util/dnsparser.c b/src/util/dnsparser.c index f187803bc..ab687414e 100644 --- a/src/util/dnsparser.c +++ b/src/util/dnsparser.c | |||
@@ -50,19 +50,19 @@ | |||
50 | * #GNUNET_SYSERR if the label is not valid for DNS names | 50 | * #GNUNET_SYSERR if the label is not valid for DNS names |
51 | */ | 51 | */ |
52 | int | 52 | int |
53 | GNUNET_DNSPARSER_check_label(const char *label) | 53 | GNUNET_DNSPARSER_check_label (const char *label) |
54 | { | 54 | { |
55 | char *output; | 55 | char *output; |
56 | size_t slen; | 56 | size_t slen; |
57 | 57 | ||
58 | if (NULL != strchr(label, '.')) | 58 | if (NULL != strchr (label, '.')) |
59 | return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */ | 59 | return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */ |
60 | if (0 == strcmp(label, "@")) /* '@' is reserved for the empty label, see #GNUNET_GNS_EMPTY_LABEL_AT */ | 60 | if (0 == strcmp (label, "@")) /* '@' is reserved for the empty label, see #GNUNET_GNS_EMPTY_LABEL_AT */ |
61 | return GNUNET_SYSERR; | 61 | return GNUNET_SYSERR; |
62 | if (IDNA_SUCCESS != idna_to_ascii_8z(label, &output, IDNA_ALLOW_UNASSIGNED)) | 62 | if (IDNA_SUCCESS != idna_to_ascii_8z (label, &output, IDNA_ALLOW_UNASSIGNED)) |
63 | return GNUNET_SYSERR; | 63 | return GNUNET_SYSERR; |
64 | slen = strlen(output); | 64 | slen = strlen (output); |
65 | free(output); | 65 | free (output); |
66 | return (slen > 63) ? GNUNET_SYSERR : GNUNET_OK; | 66 | return (slen > 63) ? GNUNET_SYSERR : GNUNET_OK; |
67 | } | 67 | } |
68 | 68 | ||
@@ -76,25 +76,25 @@ GNUNET_DNSPARSER_check_label(const char *label) | |||
76 | * #GNUNET_SYSERR if the label is not valid for DNS names | 76 | * #GNUNET_SYSERR if the label is not valid for DNS names |
77 | */ | 77 | */ |
78 | int | 78 | int |
79 | GNUNET_DNSPARSER_check_name(const char *name) | 79 | GNUNET_DNSPARSER_check_name (const char *name) |
80 | { | 80 | { |
81 | char *ldup; | 81 | char *ldup; |
82 | char *output; | 82 | char *output; |
83 | size_t slen; | 83 | size_t slen; |
84 | char *tok; | 84 | char *tok; |
85 | 85 | ||
86 | ldup = GNUNET_strdup(name); | 86 | ldup = GNUNET_strdup (name); |
87 | for (tok = strtok(ldup, "."); NULL != tok; tok = strtok(NULL, ".")) | 87 | for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, ".")) |
88 | if (GNUNET_OK != GNUNET_DNSPARSER_check_label(tok)) | 88 | if (GNUNET_OK != GNUNET_DNSPARSER_check_label (tok)) |
89 | { | 89 | { |
90 | GNUNET_free(ldup); | 90 | GNUNET_free (ldup); |
91 | return GNUNET_SYSERR; | 91 | return GNUNET_SYSERR; |
92 | } | 92 | } |
93 | GNUNET_free(ldup); | 93 | GNUNET_free (ldup); |
94 | if (IDNA_SUCCESS != idna_to_ascii_8z(name, &output, IDNA_ALLOW_UNASSIGNED)) | 94 | if (IDNA_SUCCESS != idna_to_ascii_8z (name, &output, IDNA_ALLOW_UNASSIGNED)) |
95 | return GNUNET_SYSERR; | 95 | return GNUNET_SYSERR; |
96 | slen = strlen(output); | 96 | slen = strlen (output); |
97 | free(output); | 97 | free (output); |
98 | return (slen > 253) ? GNUNET_SYSERR : GNUNET_OK; | 98 | return (slen > 253) ? GNUNET_SYSERR : GNUNET_OK; |
99 | } | 99 | } |
100 | 100 | ||
@@ -105,13 +105,13 @@ GNUNET_DNSPARSER_check_name(const char *name) | |||
105 | * @param soa record to free | 105 | * @param soa record to free |
106 | */ | 106 | */ |
107 | void | 107 | void |
108 | GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa) | 108 | GNUNET_DNSPARSER_free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa) |
109 | { | 109 | { |
110 | if (NULL == soa) | 110 | if (NULL == soa) |
111 | return; | 111 | return; |
112 | GNUNET_free_non_null(soa->mname); | 112 | GNUNET_free_non_null (soa->mname); |
113 | GNUNET_free_non_null(soa->rname); | 113 | GNUNET_free_non_null (soa->rname); |
114 | GNUNET_free(soa); | 114 | GNUNET_free (soa); |
115 | } | 115 | } |
116 | 116 | ||
117 | 117 | ||
@@ -121,12 +121,12 @@ GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa) | |||
121 | * @param cert record to free | 121 | * @param cert record to free |
122 | */ | 122 | */ |
123 | void | 123 | void |
124 | GNUNET_DNSPARSER_free_cert(struct GNUNET_DNSPARSER_CertRecord *cert) | 124 | GNUNET_DNSPARSER_free_cert (struct GNUNET_DNSPARSER_CertRecord *cert) |
125 | { | 125 | { |
126 | if (NULL == cert) | 126 | if (NULL == cert) |
127 | return; | 127 | return; |
128 | GNUNET_free_non_null(cert->certificate_data); | 128 | GNUNET_free_non_null (cert->certificate_data); |
129 | GNUNET_free(cert); | 129 | GNUNET_free (cert); |
130 | } | 130 | } |
131 | 131 | ||
132 | 132 | ||
@@ -136,12 +136,12 @@ GNUNET_DNSPARSER_free_cert(struct GNUNET_DNSPARSER_CertRecord *cert) | |||
136 | * @param srv record to free | 136 | * @param srv record to free |
137 | */ | 137 | */ |
138 | void | 138 | void |
139 | GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv) | 139 | GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv) |
140 | { | 140 | { |
141 | if (NULL == srv) | 141 | if (NULL == srv) |
142 | return; | 142 | return; |
143 | GNUNET_free_non_null(srv->target); | 143 | GNUNET_free_non_null (srv->target); |
144 | GNUNET_free(srv); | 144 | GNUNET_free (srv); |
145 | } | 145 | } |
146 | 146 | ||
147 | 147 | ||
@@ -151,12 +151,12 @@ GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv) | |||
151 | * @param mx record to free | 151 | * @param mx record to free |
152 | */ | 152 | */ |
153 | void | 153 | void |
154 | GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx) | 154 | GNUNET_DNSPARSER_free_mx (struct GNUNET_DNSPARSER_MxRecord *mx) |
155 | { | 155 | { |
156 | if (NULL == mx) | 156 | if (NULL == mx) |
157 | return; | 157 | return; |
158 | GNUNET_free_non_null(mx->mxhost); | 158 | GNUNET_free_non_null (mx->mxhost); |
159 | GNUNET_free(mx); | 159 | GNUNET_free (mx); |
160 | } | 160 | } |
161 | 161 | ||
162 | 162 | ||
@@ -166,37 +166,37 @@ GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx) | |||
166 | * @param r record to free | 166 | * @param r record to free |
167 | */ | 167 | */ |
168 | void | 168 | void |
169 | GNUNET_DNSPARSER_free_record(struct GNUNET_DNSPARSER_Record *r) | 169 | GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r) |
170 | { | 170 | { |
171 | GNUNET_free_non_null(r->name); | 171 | GNUNET_free_non_null (r->name); |
172 | switch (r->type) | 172 | switch (r->type) |
173 | { | 173 | { |
174 | case GNUNET_DNSPARSER_TYPE_MX: | 174 | case GNUNET_DNSPARSER_TYPE_MX: |
175 | GNUNET_DNSPARSER_free_mx(r->data.mx); | 175 | GNUNET_DNSPARSER_free_mx (r->data.mx); |
176 | break; | 176 | break; |
177 | 177 | ||
178 | case GNUNET_DNSPARSER_TYPE_SOA: | 178 | case GNUNET_DNSPARSER_TYPE_SOA: |
179 | GNUNET_DNSPARSER_free_soa(r->data.soa); | 179 | GNUNET_DNSPARSER_free_soa (r->data.soa); |
180 | break; | 180 | break; |
181 | 181 | ||
182 | case GNUNET_DNSPARSER_TYPE_SRV: | 182 | case GNUNET_DNSPARSER_TYPE_SRV: |
183 | GNUNET_DNSPARSER_free_srv(r->data.srv); | 183 | GNUNET_DNSPARSER_free_srv (r->data.srv); |
184 | break; | 184 | break; |
185 | 185 | ||
186 | case GNUNET_DNSPARSER_TYPE_CERT: | 186 | case GNUNET_DNSPARSER_TYPE_CERT: |
187 | GNUNET_DNSPARSER_free_cert(r->data.cert); | 187 | GNUNET_DNSPARSER_free_cert (r->data.cert); |
188 | break; | 188 | break; |
189 | 189 | ||
190 | case GNUNET_DNSPARSER_TYPE_NS: | 190 | case GNUNET_DNSPARSER_TYPE_NS: |
191 | case GNUNET_DNSPARSER_TYPE_CNAME: | 191 | case GNUNET_DNSPARSER_TYPE_CNAME: |
192 | case GNUNET_DNSPARSER_TYPE_PTR: | 192 | case GNUNET_DNSPARSER_TYPE_PTR: |
193 | GNUNET_free_non_null(r->data.hostname); | 193 | GNUNET_free_non_null (r->data.hostname); |
194 | break; | 194 | break; |
195 | 195 | ||
196 | default: | 196 | default: |
197 | GNUNET_free_non_null(r->data.raw.data); | 197 | GNUNET_free_non_null (r->data.raw.data); |
198 | break; | 198 | break; |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | 202 | ||
@@ -211,12 +211,12 @@ GNUNET_DNSPARSER_free_record(struct GNUNET_DNSPARSER_Record *r) | |||
211 | * @return name as 0-terminated C string on success, NULL if the payload is malformed | 211 | * @return name as 0-terminated C string on success, NULL if the payload is malformed |
212 | */ | 212 | */ |
213 | static char * | 213 | static char * |
214 | parse_name(const char *udp_payload, | 214 | parse_name (const char *udp_payload, |
215 | size_t udp_payload_length, | 215 | size_t udp_payload_length, |
216 | size_t *off, | 216 | size_t *off, |
217 | unsigned int depth) | 217 | unsigned int depth) |
218 | { | 218 | { |
219 | const uint8_t *input = (const uint8_t *)udp_payload; | 219 | const uint8_t *input = (const uint8_t *) udp_payload; |
220 | char *ret; | 220 | char *ret; |
221 | char *tmp; | 221 | char *tmp; |
222 | char *xstr; | 222 | char *xstr; |
@@ -225,98 +225,98 @@ parse_name(const char *udp_payload, | |||
225 | char *utf8; | 225 | char *utf8; |
226 | Idna_rc rc; | 226 | Idna_rc rc; |
227 | 227 | ||
228 | ret = GNUNET_strdup(""); | 228 | ret = GNUNET_strdup (""); |
229 | while (1) | 229 | while (1) |
230 | { | ||
231 | if (*off >= udp_payload_length) | ||
232 | { | ||
233 | GNUNET_break_op (0); | ||
234 | goto error; | ||
235 | } | ||
236 | len = input[*off]; | ||
237 | if (0 == len) | ||
238 | { | ||
239 | (*off)++; | ||
240 | break; | ||
241 | } | ||
242 | if (len < 64) | ||
230 | { | 243 | { |
231 | if (*off >= udp_payload_length) | 244 | if (*off + 1 + len > udp_payload_length) |
232 | { | 245 | { |
233 | GNUNET_break_op(0); | 246 | GNUNET_break_op (0); |
234 | goto error; | 247 | goto error; |
235 | } | 248 | } |
236 | len = input[*off]; | 249 | GNUNET_asprintf (&tmp, "%.*s", (int) len, &udp_payload[*off + 1]); |
237 | if (0 == len) | 250 | if (IDNA_SUCCESS != |
238 | { | 251 | (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED))) |
239 | (*off)++; | 252 | { |
240 | break; | 253 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
241 | } | 254 | _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"), |
242 | if (len < 64) | 255 | tmp, |
243 | { | 256 | idna_strerror (rc)); |
244 | if (*off + 1 + len > udp_payload_length) | 257 | GNUNET_free (tmp); |
245 | { | 258 | GNUNET_asprintf (&tmp, |
246 | GNUNET_break_op(0); | 259 | "%s%.*s.", |
247 | goto error; | 260 | ret, |
248 | } | 261 | (int) len, |
249 | GNUNET_asprintf(&tmp, "%.*s", (int)len, &udp_payload[*off + 1]); | 262 | &udp_payload[*off + 1]); |
250 | if (IDNA_SUCCESS != | 263 | } |
251 | (rc = idna_to_unicode_8z8z(tmp, &utf8, IDNA_ALLOW_UNASSIGNED))) | ||
252 | { | ||
253 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
254 | _("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"), | ||
255 | tmp, | ||
256 | idna_strerror(rc)); | ||
257 | GNUNET_free(tmp); | ||
258 | GNUNET_asprintf(&tmp, | ||
259 | "%s%.*s.", | ||
260 | ret, | ||
261 | (int)len, | ||
262 | &udp_payload[*off + 1]); | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | GNUNET_free(tmp); | ||
267 | GNUNET_asprintf(&tmp, "%s%s.", ret, utf8); | ||
268 | free(utf8); | ||
269 | } | ||
270 | GNUNET_free(ret); | ||
271 | ret = tmp; | ||
272 | *off += 1 + len; | ||
273 | } | ||
274 | else if ((64 | 128) == (len & (64 | 128))) | ||
275 | { | ||
276 | if (depth > 32) | ||
277 | { | ||
278 | GNUNET_break_op(0); | ||
279 | goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */ | ||
280 | } | ||
281 | /* pointer to string */ | ||
282 | if (*off + 1 > udp_payload_length) | ||
283 | { | ||
284 | GNUNET_break_op(0); | ||
285 | goto error; | ||
286 | } | ||
287 | xoff = ((len - (64 | 128)) << 8) + input[*off + 1]; | ||
288 | xstr = parse_name(udp_payload, udp_payload_length, &xoff, depth + 1); | ||
289 | if (NULL == xstr) | ||
290 | { | ||
291 | GNUNET_break_op(0); | ||
292 | goto error; | ||
293 | } | ||
294 | GNUNET_asprintf(&tmp, "%s%s.", ret, xstr); | ||
295 | GNUNET_free(ret); | ||
296 | GNUNET_free(xstr); | ||
297 | ret = tmp; | ||
298 | if (strlen(ret) > udp_payload_length) | ||
299 | { | ||
300 | GNUNET_break_op(0); | ||
301 | goto error; /* we are looping (building an infinite string) */ | ||
302 | } | ||
303 | *off += 2; | ||
304 | /* pointers always terminate names */ | ||
305 | break; | ||
306 | } | ||
307 | else | 264 | else |
308 | { | 265 | { |
309 | /* neither pointer nor inline string, not supported... */ | 266 | GNUNET_free (tmp); |
310 | GNUNET_break_op(0); | 267 | GNUNET_asprintf (&tmp, "%s%s.", ret, utf8); |
311 | goto error; | 268 | free (utf8); |
312 | } | 269 | } |
270 | GNUNET_free (ret); | ||
271 | ret = tmp; | ||
272 | *off += 1 + len; | ||
273 | } | ||
274 | else if ((64 | 128) == (len & (64 | 128))) | ||
275 | { | ||
276 | if (depth > 32) | ||
277 | { | ||
278 | GNUNET_break_op (0); | ||
279 | goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */ | ||
280 | } | ||
281 | /* pointer to string */ | ||
282 | if (*off + 1 > udp_payload_length) | ||
283 | { | ||
284 | GNUNET_break_op (0); | ||
285 | goto error; | ||
286 | } | ||
287 | xoff = ((len - (64 | 128)) << 8) + input[*off + 1]; | ||
288 | xstr = parse_name (udp_payload, udp_payload_length, &xoff, depth + 1); | ||
289 | if (NULL == xstr) | ||
290 | { | ||
291 | GNUNET_break_op (0); | ||
292 | goto error; | ||
293 | } | ||
294 | GNUNET_asprintf (&tmp, "%s%s.", ret, xstr); | ||
295 | GNUNET_free (ret); | ||
296 | GNUNET_free (xstr); | ||
297 | ret = tmp; | ||
298 | if (strlen (ret) > udp_payload_length) | ||
299 | { | ||
300 | GNUNET_break_op (0); | ||
301 | goto error; /* we are looping (building an infinite string) */ | ||
302 | } | ||
303 | *off += 2; | ||
304 | /* pointers always terminate names */ | ||
305 | break; | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | /* neither pointer nor inline string, not supported... */ | ||
310 | GNUNET_break_op (0); | ||
311 | goto error; | ||
313 | } | 312 | } |
314 | if (0 < strlen(ret)) | 313 | } |
315 | ret[strlen(ret) - 1] = '\0'; /* eat tailing '.' */ | 314 | if (0 < strlen (ret)) |
315 | ret[strlen (ret) - 1] = '\0'; /* eat tailing '.' */ | ||
316 | return ret; | 316 | return ret; |
317 | error: | 317 | error: |
318 | GNUNET_break_op(0); | 318 | GNUNET_break_op (0); |
319 | GNUNET_free(ret); | 319 | GNUNET_free (ret); |
320 | return NULL; | 320 | return NULL; |
321 | } | 321 | } |
322 | 322 | ||
@@ -331,11 +331,11 @@ error: | |||
331 | * @return name as 0-terminated C string on success, NULL if the payload is malformed | 331 | * @return name as 0-terminated C string on success, NULL if the payload is malformed |
332 | */ | 332 | */ |
333 | char * | 333 | char * |
334 | GNUNET_DNSPARSER_parse_name(const char *udp_payload, | 334 | GNUNET_DNSPARSER_parse_name (const char *udp_payload, |
335 | size_t udp_payload_length, | 335 | size_t udp_payload_length, |
336 | size_t *off) | 336 | size_t *off) |
337 | { | 337 | { |
338 | return parse_name(udp_payload, udp_payload_length, off, 0); | 338 | return parse_name (udp_payload, udp_payload_length, off, 0); |
339 | } | 339 | } |
340 | 340 | ||
341 | 341 | ||
@@ -350,30 +350,30 @@ GNUNET_DNSPARSER_parse_name(const char *udp_payload, | |||
350 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed | 350 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed |
351 | */ | 351 | */ |
352 | int | 352 | int |
353 | GNUNET_DNSPARSER_parse_query(const char *udp_payload, | 353 | GNUNET_DNSPARSER_parse_query (const char *udp_payload, |
354 | size_t udp_payload_length, | 354 | size_t udp_payload_length, |
355 | size_t *off, | 355 | size_t *off, |
356 | struct GNUNET_DNSPARSER_Query *q) | 356 | struct GNUNET_DNSPARSER_Query *q) |
357 | { | 357 | { |
358 | char *name; | 358 | char *name; |
359 | struct GNUNET_TUN_DnsQueryLine ql; | 359 | struct GNUNET_TUN_DnsQueryLine ql; |
360 | 360 | ||
361 | name = GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | 361 | name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); |
362 | if (NULL == name) | 362 | if (NULL == name) |
363 | { | 363 | { |
364 | GNUNET_break_op(0); | 364 | GNUNET_break_op (0); |
365 | return GNUNET_SYSERR; | 365 | return GNUNET_SYSERR; |
366 | } | 366 | } |
367 | q->name = name; | 367 | q->name = name; |
368 | if (*off + sizeof(struct GNUNET_TUN_DnsQueryLine) > udp_payload_length) | 368 | if (*off + sizeof(struct GNUNET_TUN_DnsQueryLine) > udp_payload_length) |
369 | { | 369 | { |
370 | GNUNET_break_op(0); | 370 | GNUNET_break_op (0); |
371 | return GNUNET_SYSERR; | 371 | return GNUNET_SYSERR; |
372 | } | 372 | } |
373 | GNUNET_memcpy(&ql, &udp_payload[*off], sizeof(ql)); | 373 | GNUNET_memcpy (&ql, &udp_payload[*off], sizeof(ql)); |
374 | *off += sizeof(ql); | 374 | *off += sizeof(ql); |
375 | q->type = ntohs(ql.type); | 375 | q->type = ntohs (ql.type); |
376 | q->dns_traffic_class = ntohs(ql.dns_traffic_class); | 376 | q->dns_traffic_class = ntohs (ql.dns_traffic_class); |
377 | return GNUNET_OK; | 377 | return GNUNET_OK; |
378 | } | 378 | } |
379 | 379 | ||
@@ -388,36 +388,36 @@ GNUNET_DNSPARSER_parse_query(const char *udp_payload, | |||
388 | * @return the parsed SOA record, NULL on error | 388 | * @return the parsed SOA record, NULL on error |
389 | */ | 389 | */ |
390 | struct GNUNET_DNSPARSER_SoaRecord * | 390 | struct GNUNET_DNSPARSER_SoaRecord * |
391 | GNUNET_DNSPARSER_parse_soa(const char *udp_payload, | 391 | GNUNET_DNSPARSER_parse_soa (const char *udp_payload, |
392 | size_t udp_payload_length, | 392 | size_t udp_payload_length, |
393 | size_t *off) | 393 | size_t *off) |
394 | { | 394 | { |
395 | struct GNUNET_DNSPARSER_SoaRecord *soa; | 395 | struct GNUNET_DNSPARSER_SoaRecord *soa; |
396 | struct GNUNET_TUN_DnsSoaRecord soa_bin; | 396 | struct GNUNET_TUN_DnsSoaRecord soa_bin; |
397 | size_t old_off; | 397 | size_t old_off; |
398 | 398 | ||
399 | old_off = *off; | 399 | old_off = *off; |
400 | soa = GNUNET_new(struct GNUNET_DNSPARSER_SoaRecord); | 400 | soa = GNUNET_new (struct GNUNET_DNSPARSER_SoaRecord); |
401 | soa->mname = | 401 | soa->mname = |
402 | GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | 402 | GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); |
403 | soa->rname = | 403 | soa->rname = |
404 | GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | 404 | GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); |
405 | if ((NULL == soa->mname) || (NULL == soa->rname) || | 405 | if ((NULL == soa->mname) || (NULL == soa->rname) || |
406 | (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length)) | 406 | (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length)) |
407 | { | 407 | { |
408 | GNUNET_break_op(0); | 408 | GNUNET_break_op (0); |
409 | GNUNET_DNSPARSER_free_soa(soa); | 409 | GNUNET_DNSPARSER_free_soa (soa); |
410 | *off = old_off; | 410 | *off = old_off; |
411 | return NULL; | 411 | return NULL; |
412 | } | 412 | } |
413 | GNUNET_memcpy(&soa_bin, | 413 | GNUNET_memcpy (&soa_bin, |
414 | &udp_payload[*off], | 414 | &udp_payload[*off], |
415 | sizeof(struct GNUNET_TUN_DnsSoaRecord)); | 415 | sizeof(struct GNUNET_TUN_DnsSoaRecord)); |
416 | soa->serial = ntohl(soa_bin.serial); | 416 | soa->serial = ntohl (soa_bin.serial); |
417 | soa->refresh = ntohl(soa_bin.refresh); | 417 | soa->refresh = ntohl (soa_bin.refresh); |
418 | soa->retry = ntohl(soa_bin.retry); | 418 | soa->retry = ntohl (soa_bin.retry); |
419 | soa->expire = ntohl(soa_bin.expire); | 419 | soa->expire = ntohl (soa_bin.expire); |
420 | soa->minimum_ttl = ntohl(soa_bin.minimum); | 420 | soa->minimum_ttl = ntohl (soa_bin.minimum); |
421 | (*off) += sizeof(struct GNUNET_TUN_DnsSoaRecord); | 421 | (*off) += sizeof(struct GNUNET_TUN_DnsSoaRecord); |
422 | return soa; | 422 | return soa; |
423 | } | 423 | } |
@@ -433,9 +433,9 @@ GNUNET_DNSPARSER_parse_soa(const char *udp_payload, | |||
433 | * @return the parsed MX record, NULL on error | 433 | * @return the parsed MX record, NULL on error |
434 | */ | 434 | */ |
435 | struct GNUNET_DNSPARSER_MxRecord * | 435 | struct GNUNET_DNSPARSER_MxRecord * |
436 | GNUNET_DNSPARSER_parse_mx(const char *udp_payload, | 436 | GNUNET_DNSPARSER_parse_mx (const char *udp_payload, |
437 | size_t udp_payload_length, | 437 | size_t udp_payload_length, |
438 | size_t *off) | 438 | size_t *off) |
439 | { | 439 | { |
440 | struct GNUNET_DNSPARSER_MxRecord *mx; | 440 | struct GNUNET_DNSPARSER_MxRecord *mx; |
441 | uint16_t mxpref; | 441 | uint16_t mxpref; |
@@ -443,23 +443,23 @@ GNUNET_DNSPARSER_parse_mx(const char *udp_payload, | |||
443 | 443 | ||
444 | old_off = *off; | 444 | old_off = *off; |
445 | if (*off + sizeof(uint16_t) > udp_payload_length) | 445 | if (*off + sizeof(uint16_t) > udp_payload_length) |
446 | { | 446 | { |
447 | GNUNET_break_op(0); | 447 | GNUNET_break_op (0); |
448 | return NULL; | 448 | return NULL; |
449 | } | 449 | } |
450 | GNUNET_memcpy(&mxpref, &udp_payload[*off], sizeof(uint16_t)); | 450 | GNUNET_memcpy (&mxpref, &udp_payload[*off], sizeof(uint16_t)); |
451 | (*off) += sizeof(uint16_t); | 451 | (*off) += sizeof(uint16_t); |
452 | mx = GNUNET_new(struct GNUNET_DNSPARSER_MxRecord); | 452 | mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); |
453 | mx->preference = ntohs(mxpref); | 453 | mx->preference = ntohs (mxpref); |
454 | mx->mxhost = | 454 | mx->mxhost = |
455 | GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | 455 | GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); |
456 | if (NULL == mx->mxhost) | 456 | if (NULL == mx->mxhost) |
457 | { | 457 | { |
458 | GNUNET_break_op(0); | 458 | GNUNET_break_op (0); |
459 | GNUNET_DNSPARSER_free_mx(mx); | 459 | GNUNET_DNSPARSER_free_mx (mx); |
460 | *off = old_off; | 460 | *off = old_off; |
461 | return NULL; | 461 | return NULL; |
462 | } | 462 | } |
463 | return mx; | 463 | return mx; |
464 | } | 464 | } |
465 | 465 | ||
@@ -474,9 +474,9 @@ GNUNET_DNSPARSER_parse_mx(const char *udp_payload, | |||
474 | * @return the parsed SRV record, NULL on error | 474 | * @return the parsed SRV record, NULL on error |
475 | */ | 475 | */ |
476 | struct GNUNET_DNSPARSER_SrvRecord * | 476 | struct GNUNET_DNSPARSER_SrvRecord * |
477 | GNUNET_DNSPARSER_parse_srv(const char *udp_payload, | 477 | GNUNET_DNSPARSER_parse_srv (const char *udp_payload, |
478 | size_t udp_payload_length, | 478 | size_t udp_payload_length, |
479 | size_t *off) | 479 | size_t *off) |
480 | { | 480 | { |
481 | struct GNUNET_DNSPARSER_SrvRecord *srv; | 481 | struct GNUNET_DNSPARSER_SrvRecord *srv; |
482 | struct GNUNET_TUN_DnsSrvRecord srv_bin; | 482 | struct GNUNET_TUN_DnsSrvRecord srv_bin; |
@@ -485,22 +485,22 @@ GNUNET_DNSPARSER_parse_srv(const char *udp_payload, | |||
485 | old_off = *off; | 485 | old_off = *off; |
486 | if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length) | 486 | if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length) |
487 | return NULL; | 487 | return NULL; |
488 | GNUNET_memcpy(&srv_bin, | 488 | GNUNET_memcpy (&srv_bin, |
489 | &udp_payload[*off], | 489 | &udp_payload[*off], |
490 | sizeof(struct GNUNET_TUN_DnsSrvRecord)); | 490 | sizeof(struct GNUNET_TUN_DnsSrvRecord)); |
491 | (*off) += sizeof(struct GNUNET_TUN_DnsSrvRecord); | 491 | (*off) += sizeof(struct GNUNET_TUN_DnsSrvRecord); |
492 | srv = GNUNET_new(struct GNUNET_DNSPARSER_SrvRecord); | 492 | srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord); |
493 | srv->priority = ntohs(srv_bin.prio); | 493 | srv->priority = ntohs (srv_bin.prio); |
494 | srv->weight = ntohs(srv_bin.weight); | 494 | srv->weight = ntohs (srv_bin.weight); |
495 | srv->port = ntohs(srv_bin.port); | 495 | srv->port = ntohs (srv_bin.port); |
496 | srv->target = | 496 | srv->target = |
497 | GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | 497 | GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); |
498 | if (NULL == srv->target) | 498 | if (NULL == srv->target) |
499 | { | 499 | { |
500 | GNUNET_DNSPARSER_free_srv(srv); | 500 | GNUNET_DNSPARSER_free_srv (srv); |
501 | *off = old_off; | 501 | *off = old_off; |
502 | return NULL; | 502 | return NULL; |
503 | } | 503 | } |
504 | return srv; | 504 | return srv; |
505 | } | 505 | } |
506 | 506 | ||
@@ -515,31 +515,31 @@ GNUNET_DNSPARSER_parse_srv(const char *udp_payload, | |||
515 | * @return the parsed CERT record, NULL on error | 515 | * @return the parsed CERT record, NULL on error |
516 | */ | 516 | */ |
517 | struct GNUNET_DNSPARSER_CertRecord * | 517 | struct GNUNET_DNSPARSER_CertRecord * |
518 | GNUNET_DNSPARSER_parse_cert(const char *udp_payload, | 518 | GNUNET_DNSPARSER_parse_cert (const char *udp_payload, |
519 | size_t udp_payload_length, | 519 | size_t udp_payload_length, |
520 | size_t *off) | 520 | size_t *off) |
521 | { | 521 | { |
522 | struct GNUNET_DNSPARSER_CertRecord *cert; | 522 | struct GNUNET_DNSPARSER_CertRecord *cert; |
523 | struct GNUNET_TUN_DnsCertRecord dcert; | 523 | struct GNUNET_TUN_DnsCertRecord dcert; |
524 | 524 | ||
525 | if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length) | 525 | if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length) |
526 | { | 526 | { |
527 | GNUNET_break_op(0); | 527 | GNUNET_break_op (0); |
528 | return NULL; | 528 | return NULL; |
529 | } | 529 | } |
530 | GNUNET_memcpy(&dcert, | 530 | GNUNET_memcpy (&dcert, |
531 | &udp_payload[*off], | 531 | &udp_payload[*off], |
532 | sizeof(struct GNUNET_TUN_DnsCertRecord)); | 532 | sizeof(struct GNUNET_TUN_DnsCertRecord)); |
533 | (*off) += sizeof(struct GNUNET_TUN_DnsCertRecord); | 533 | (*off) += sizeof(struct GNUNET_TUN_DnsCertRecord); |
534 | cert = GNUNET_new(struct GNUNET_DNSPARSER_CertRecord); | 534 | cert = GNUNET_new (struct GNUNET_DNSPARSER_CertRecord); |
535 | cert->cert_type = ntohs(dcert.cert_type); | 535 | cert->cert_type = ntohs (dcert.cert_type); |
536 | cert->cert_tag = ntohs(dcert.cert_tag); | 536 | cert->cert_tag = ntohs (dcert.cert_tag); |
537 | cert->algorithm = dcert.algorithm; | 537 | cert->algorithm = dcert.algorithm; |
538 | cert->certificate_size = udp_payload_length - (*off); | 538 | cert->certificate_size = udp_payload_length - (*off); |
539 | cert->certificate_data = GNUNET_malloc(cert->certificate_size); | 539 | cert->certificate_data = GNUNET_malloc (cert->certificate_size); |
540 | GNUNET_memcpy(cert->certificate_data, | 540 | GNUNET_memcpy (cert->certificate_data, |
541 | &udp_payload[*off], | 541 | &udp_payload[*off], |
542 | cert->certificate_size); | 542 | cert->certificate_size); |
543 | (*off) += cert->certificate_size; | 543 | (*off) += cert->certificate_size; |
544 | return cert; | 544 | return cert; |
545 | } | 545 | } |
@@ -556,89 +556,89 @@ GNUNET_DNSPARSER_parse_cert(const char *udp_payload, | |||
556 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed | 556 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed |
557 | */ | 557 | */ |
558 | int | 558 | int |
559 | GNUNET_DNSPARSER_parse_record(const char *udp_payload, | 559 | GNUNET_DNSPARSER_parse_record (const char *udp_payload, |
560 | size_t udp_payload_length, | 560 | size_t udp_payload_length, |
561 | size_t *off, | 561 | size_t *off, |
562 | struct GNUNET_DNSPARSER_Record *r) | 562 | struct GNUNET_DNSPARSER_Record *r) |
563 | { | 563 | { |
564 | char *name; | 564 | char *name; |
565 | struct GNUNET_TUN_DnsRecordLine rl; | 565 | struct GNUNET_TUN_DnsRecordLine rl; |
566 | size_t old_off; | 566 | size_t old_off; |
567 | uint16_t data_len; | 567 | uint16_t data_len; |
568 | 568 | ||
569 | name = GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | 569 | name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); |
570 | if (NULL == name) | 570 | if (NULL == name) |
571 | { | 571 | { |
572 | GNUNET_break_op(0); | 572 | GNUNET_break_op (0); |
573 | return GNUNET_SYSERR; | 573 | return GNUNET_SYSERR; |
574 | } | 574 | } |
575 | r->name = name; | 575 | r->name = name; |
576 | if (*off + sizeof(struct GNUNET_TUN_DnsRecordLine) > udp_payload_length) | 576 | if (*off + sizeof(struct GNUNET_TUN_DnsRecordLine) > udp_payload_length) |
577 | { | ||
578 | GNUNET_break_op (0); | ||
579 | return GNUNET_SYSERR; | ||
580 | } | ||
581 | GNUNET_memcpy (&rl, &udp_payload[*off], sizeof(rl)); | ||
582 | (*off) += sizeof(rl); | ||
583 | r->type = ntohs (rl.type); | ||
584 | r->dns_traffic_class = ntohs (rl.dns_traffic_class); | ||
585 | r->expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
586 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, ntohl (rl.ttl))); | ||
587 | data_len = ntohs (rl.data_len); | ||
588 | if (*off + data_len > udp_payload_length) | ||
589 | { | ||
590 | GNUNET_break_op (0); | ||
591 | return GNUNET_SYSERR; | ||
592 | } | ||
593 | old_off = *off; | ||
594 | switch (r->type) | ||
595 | { | ||
596 | case GNUNET_DNSPARSER_TYPE_NS: | ||
597 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
598 | case GNUNET_DNSPARSER_TYPE_DNAME: | ||
599 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
600 | r->data.hostname = | ||
601 | GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off); | ||
602 | if ((NULL == r->data.hostname) || (old_off + data_len != *off)) | ||
603 | return GNUNET_SYSERR; | ||
604 | return GNUNET_OK; | ||
605 | |||
606 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
607 | r->data.soa = | ||
608 | GNUNET_DNSPARSER_parse_soa (udp_payload, udp_payload_length, off); | ||
609 | if ((NULL == r->data.soa) || (old_off + data_len != *off)) | ||
577 | { | 610 | { |
578 | GNUNET_break_op(0); | 611 | GNUNET_break_op (0); |
579 | return GNUNET_SYSERR; | 612 | return GNUNET_SYSERR; |
580 | } | 613 | } |
581 | GNUNET_memcpy(&rl, &udp_payload[*off], sizeof(rl)); | 614 | return GNUNET_OK; |
582 | (*off) += sizeof(rl); | 615 | |
583 | r->type = ntohs(rl.type); | 616 | case GNUNET_DNSPARSER_TYPE_MX: |
584 | r->dns_traffic_class = ntohs(rl.dns_traffic_class); | 617 | r->data.mx = |
585 | r->expiration_time = GNUNET_TIME_relative_to_absolute( | 618 | GNUNET_DNSPARSER_parse_mx (udp_payload, udp_payload_length, off); |
586 | GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, ntohl(rl.ttl))); | 619 | if ((NULL == r->data.mx) || (old_off + data_len != *off)) |
587 | data_len = ntohs(rl.data_len); | ||
588 | if (*off + data_len > udp_payload_length) | ||
589 | { | 620 | { |
590 | GNUNET_break_op(0); | 621 | GNUNET_break_op (0); |
591 | return GNUNET_SYSERR; | 622 | return GNUNET_SYSERR; |
592 | } | 623 | } |
593 | old_off = *off; | 624 | return GNUNET_OK; |
594 | switch (r->type) | 625 | |
626 | case GNUNET_DNSPARSER_TYPE_SRV: | ||
627 | r->data.srv = | ||
628 | GNUNET_DNSPARSER_parse_srv (udp_payload, udp_payload_length, off); | ||
629 | if ((NULL == r->data.srv) || (old_off + data_len != *off)) | ||
595 | { | 630 | { |
596 | case GNUNET_DNSPARSER_TYPE_NS: | 631 | GNUNET_break_op (0); |
597 | case GNUNET_DNSPARSER_TYPE_CNAME: | 632 | return GNUNET_SYSERR; |
598 | case GNUNET_DNSPARSER_TYPE_DNAME: | ||
599 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
600 | r->data.hostname = | ||
601 | GNUNET_DNSPARSER_parse_name(udp_payload, udp_payload_length, off); | ||
602 | if ((NULL == r->data.hostname) || (old_off + data_len != *off)) | ||
603 | return GNUNET_SYSERR; | ||
604 | return GNUNET_OK; | ||
605 | |||
606 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
607 | r->data.soa = | ||
608 | GNUNET_DNSPARSER_parse_soa(udp_payload, udp_payload_length, off); | ||
609 | if ((NULL == r->data.soa) || (old_off + data_len != *off)) | ||
610 | { | ||
611 | GNUNET_break_op(0); | ||
612 | return GNUNET_SYSERR; | ||
613 | } | ||
614 | return GNUNET_OK; | ||
615 | |||
616 | case GNUNET_DNSPARSER_TYPE_MX: | ||
617 | r->data.mx = | ||
618 | GNUNET_DNSPARSER_parse_mx(udp_payload, udp_payload_length, off); | ||
619 | if ((NULL == r->data.mx) || (old_off + data_len != *off)) | ||
620 | { | ||
621 | GNUNET_break_op(0); | ||
622 | return GNUNET_SYSERR; | ||
623 | } | ||
624 | return GNUNET_OK; | ||
625 | |||
626 | case GNUNET_DNSPARSER_TYPE_SRV: | ||
627 | r->data.srv = | ||
628 | GNUNET_DNSPARSER_parse_srv(udp_payload, udp_payload_length, off); | ||
629 | if ((NULL == r->data.srv) || (old_off + data_len != *off)) | ||
630 | { | ||
631 | GNUNET_break_op(0); | ||
632 | return GNUNET_SYSERR; | ||
633 | } | ||
634 | return GNUNET_OK; | ||
635 | |||
636 | default: | ||
637 | r->data.raw.data = GNUNET_malloc(data_len); | ||
638 | r->data.raw.data_len = data_len; | ||
639 | GNUNET_memcpy(r->data.raw.data, &udp_payload[*off], data_len); | ||
640 | break; | ||
641 | } | 633 | } |
634 | return GNUNET_OK; | ||
635 | |||
636 | default: | ||
637 | r->data.raw.data = GNUNET_malloc (data_len); | ||
638 | r->data.raw.data_len = data_len; | ||
639 | GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len); | ||
640 | break; | ||
641 | } | ||
642 | (*off) += data_len; | 642 | (*off) += data_len; |
643 | return GNUNET_OK; | 643 | return GNUNET_OK; |
644 | } | 644 | } |
@@ -653,7 +653,7 @@ GNUNET_DNSPARSER_parse_record(const char *udp_payload, | |||
653 | * @return NULL on error, otherwise the parsed packet | 653 | * @return NULL on error, otherwise the parsed packet |
654 | */ | 654 | */ |
655 | struct GNUNET_DNSPARSER_Packet * | 655 | struct GNUNET_DNSPARSER_Packet * |
656 | GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length) | 656 | GNUNET_DNSPARSER_parse (const char *udp_payload, size_t udp_payload_length) |
657 | { | 657 | { |
658 | struct GNUNET_DNSPARSER_Packet *p; | 658 | struct GNUNET_DNSPARSER_Packet *p; |
659 | const struct GNUNET_TUN_DnsHeader *dns; | 659 | const struct GNUNET_TUN_DnsHeader *dns; |
@@ -662,67 +662,67 @@ GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length) | |||
662 | 662 | ||
663 | if (udp_payload_length < sizeof(struct GNUNET_TUN_DnsHeader)) | 663 | if (udp_payload_length < sizeof(struct GNUNET_TUN_DnsHeader)) |
664 | return NULL; | 664 | return NULL; |
665 | dns = (const struct GNUNET_TUN_DnsHeader *)udp_payload; | 665 | dns = (const struct GNUNET_TUN_DnsHeader *) udp_payload; |
666 | off = sizeof(struct GNUNET_TUN_DnsHeader); | 666 | off = sizeof(struct GNUNET_TUN_DnsHeader); |
667 | p = GNUNET_new(struct GNUNET_DNSPARSER_Packet); | 667 | p = GNUNET_new (struct GNUNET_DNSPARSER_Packet); |
668 | p->flags = dns->flags; | 668 | p->flags = dns->flags; |
669 | p->id = dns->id; | 669 | p->id = dns->id; |
670 | n = ntohs(dns->query_count); | 670 | n = ntohs (dns->query_count); |
671 | if (n > 0) | 671 | if (n > 0) |
672 | { | 672 | { |
673 | p->queries = GNUNET_new_array(n, struct GNUNET_DNSPARSER_Query); | 673 | p->queries = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Query); |
674 | p->num_queries = n; | 674 | p->num_queries = n; |
675 | for (unsigned int i = 0; i < n; i++) | 675 | for (unsigned int i = 0; i < n; i++) |
676 | if (GNUNET_OK != GNUNET_DNSPARSER_parse_query(udp_payload, | 676 | if (GNUNET_OK != GNUNET_DNSPARSER_parse_query (udp_payload, |
677 | udp_payload_length, | ||
678 | &off, | ||
679 | &p->queries[i])) | ||
680 | goto error; | ||
681 | } | ||
682 | n = ntohs (dns->answer_rcount); | ||
683 | if (n > 0) | ||
684 | { | ||
685 | p->answers = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record); | ||
686 | p->num_answers = n; | ||
687 | for (unsigned int i = 0; i < n; i++) | ||
688 | if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload, | ||
677 | udp_payload_length, | 689 | udp_payload_length, |
678 | &off, | 690 | &off, |
679 | &p->queries[i])) | 691 | &p->answers[i])) |
680 | goto error; | 692 | goto error; |
681 | } | 693 | } |
682 | n = ntohs(dns->answer_rcount); | 694 | n = ntohs (dns->authority_rcount); |
683 | if (n > 0) | 695 | if (n > 0) |
684 | { | 696 | { |
685 | p->answers = GNUNET_new_array(n, struct GNUNET_DNSPARSER_Record); | 697 | p->authority_records = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record); |
686 | p->num_answers = n; | 698 | p->num_authority_records = n; |
687 | for (unsigned int i = 0; i < n; i++) | 699 | for (unsigned int i = 0; i < n; i++) |
688 | if (GNUNET_OK != GNUNET_DNSPARSER_parse_record(udp_payload, | 700 | if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload, |
689 | udp_payload_length, | 701 | udp_payload_length, |
690 | &off, | 702 | &off, |
691 | &p->answers[i])) | 703 | &p->authority_records[i])) |
692 | goto error; | 704 | goto error; |
693 | } | 705 | } |
694 | n = ntohs(dns->authority_rcount); | 706 | n = ntohs (dns->additional_rcount); |
695 | if (n > 0) | ||
696 | { | ||
697 | p->authority_records = GNUNET_new_array(n, struct GNUNET_DNSPARSER_Record); | ||
698 | p->num_authority_records = n; | ||
699 | for (unsigned int i = 0; i < n; i++) | ||
700 | if (GNUNET_OK != GNUNET_DNSPARSER_parse_record(udp_payload, | ||
701 | udp_payload_length, | ||
702 | &off, | ||
703 | &p->authority_records[i])) | ||
704 | goto error; | ||
705 | } | ||
706 | n = ntohs(dns->additional_rcount); | ||
707 | if (n > 0) | 707 | if (n > 0) |
708 | { | ||
709 | p->additional_records = | ||
710 | GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record); | ||
711 | p->num_additional_records = n; | ||
712 | for (unsigned int i = 0; i < n; i++) | ||
708 | { | 713 | { |
709 | p->additional_records = | 714 | if (GNUNET_OK != |
710 | GNUNET_new_array(n, struct GNUNET_DNSPARSER_Record); | 715 | GNUNET_DNSPARSER_parse_record (udp_payload, |
711 | p->num_additional_records = n; | 716 | udp_payload_length, |
712 | for (unsigned int i = 0; i < n; i++) | 717 | &off, |
713 | { | 718 | &p->additional_records[i])) |
714 | if (GNUNET_OK != | 719 | goto error; |
715 | GNUNET_DNSPARSER_parse_record(udp_payload, | ||
716 | udp_payload_length, | ||
717 | &off, | ||
718 | &p->additional_records[i])) | ||
719 | goto error; | ||
720 | } | ||
721 | } | 720 | } |
721 | } | ||
722 | return p; | 722 | return p; |
723 | error: | 723 | error: |
724 | GNUNET_break_op(0); | 724 | GNUNET_break_op (0); |
725 | GNUNET_DNSPARSER_free_packet(p); | 725 | GNUNET_DNSPARSER_free_packet (p); |
726 | return NULL; | 726 | return NULL; |
727 | } | 727 | } |
728 | 728 | ||
@@ -734,44 +734,45 @@ error: | |||
734 | * @return the newly allocated record | 734 | * @return the newly allocated record |
735 | */ | 735 | */ |
736 | struct GNUNET_DNSPARSER_Record * | 736 | struct GNUNET_DNSPARSER_Record * |
737 | GNUNET_DNSPARSER_duplicate_record(const struct GNUNET_DNSPARSER_Record *r) | 737 | GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r) |
738 | { | 738 | { |
739 | struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup(r, sizeof(*r)); | 739 | struct GNUNET_DNSPARSER_Record *dup = GNUNET_memdup (r, sizeof(*r)); |
740 | 740 | ||
741 | dup->name = GNUNET_strdup(r->name); | 741 | dup->name = GNUNET_strdup (r->name); |
742 | switch (r->type) | 742 | switch (r->type) |
743 | { | 743 | { |
744 | case GNUNET_DNSPARSER_TYPE_NS: | 744 | case GNUNET_DNSPARSER_TYPE_NS: |
745 | case GNUNET_DNSPARSER_TYPE_CNAME: | 745 | case GNUNET_DNSPARSER_TYPE_CNAME: |
746 | case GNUNET_DNSPARSER_TYPE_PTR: { | 746 | case GNUNET_DNSPARSER_TYPE_PTR: { |
747 | dup->data.hostname = GNUNET_strdup(r->data.hostname); | 747 | dup->data.hostname = GNUNET_strdup (r->data.hostname); |
748 | break; | 748 | break; |
749 | } | 749 | } |
750 | 750 | ||
751 | case GNUNET_DNSPARSER_TYPE_SOA: { | 751 | case GNUNET_DNSPARSER_TYPE_SOA: { |
752 | dup->data.soa = GNUNET_DNSPARSER_duplicate_soa_record(r->data.soa); | 752 | dup->data.soa = GNUNET_DNSPARSER_duplicate_soa_record (r->data.soa); |
753 | break; | 753 | break; |
754 | } | 754 | } |
755 | 755 | ||
756 | case GNUNET_DNSPARSER_TYPE_CERT: { | 756 | case GNUNET_DNSPARSER_TYPE_CERT: { |
757 | dup->data.cert = GNUNET_DNSPARSER_duplicate_cert_record(r->data.cert); | 757 | dup->data.cert = GNUNET_DNSPARSER_duplicate_cert_record (r->data.cert); |
758 | break; | 758 | break; |
759 | } | 759 | } |
760 | 760 | ||
761 | case GNUNET_DNSPARSER_TYPE_MX: { | 761 | case GNUNET_DNSPARSER_TYPE_MX: { |
762 | dup->data.mx = GNUNET_DNSPARSER_duplicate_mx_record(r->data.mx); | 762 | dup->data.mx = GNUNET_DNSPARSER_duplicate_mx_record (r->data.mx); |
763 | break; | 763 | break; |
764 | } | 764 | } |
765 | 765 | ||
766 | case GNUNET_DNSPARSER_TYPE_SRV: { | 766 | case GNUNET_DNSPARSER_TYPE_SRV: { |
767 | dup->data.srv = GNUNET_DNSPARSER_duplicate_srv_record(r->data.srv); | 767 | dup->data.srv = GNUNET_DNSPARSER_duplicate_srv_record (r->data.srv); |
768 | break; | 768 | break; |
769 | } | 769 | } |
770 | 770 | ||
771 | default: { | 771 | default: { |
772 | dup->data.raw.data = GNUNET_memdup(r->data.raw.data, r->data.raw.data_len); | 772 | dup->data.raw.data = GNUNET_memdup (r->data.raw.data, |
773 | } | 773 | r->data.raw.data_len); |
774 | } | 774 | } |
775 | } | ||
775 | return dup; | 776 | return dup; |
776 | } | 777 | } |
777 | 778 | ||
@@ -783,13 +784,13 @@ GNUNET_DNSPARSER_duplicate_record(const struct GNUNET_DNSPARSER_Record *r) | |||
783 | * @return the newly allocated record | 784 | * @return the newly allocated record |
784 | */ | 785 | */ |
785 | struct GNUNET_DNSPARSER_SoaRecord * | 786 | struct GNUNET_DNSPARSER_SoaRecord * |
786 | GNUNET_DNSPARSER_duplicate_soa_record( | 787 | GNUNET_DNSPARSER_duplicate_soa_record ( |
787 | const struct GNUNET_DNSPARSER_SoaRecord *r) | 788 | const struct GNUNET_DNSPARSER_SoaRecord *r) |
788 | { | 789 | { |
789 | struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup(r, sizeof(*r)); | 790 | struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof(*r)); |
790 | 791 | ||
791 | dup->mname = GNUNET_strdup(r->mname); | 792 | dup->mname = GNUNET_strdup (r->mname); |
792 | dup->rname = GNUNET_strdup(r->rname); | 793 | dup->rname = GNUNET_strdup (r->rname); |
793 | return dup; | 794 | return dup; |
794 | } | 795 | } |
795 | 796 | ||
@@ -801,12 +802,12 @@ GNUNET_DNSPARSER_duplicate_soa_record( | |||
801 | * @return the newly allocated record | 802 | * @return the newly allocated record |
802 | */ | 803 | */ |
803 | struct GNUNET_DNSPARSER_CertRecord * | 804 | struct GNUNET_DNSPARSER_CertRecord * |
804 | GNUNET_DNSPARSER_duplicate_cert_record( | 805 | GNUNET_DNSPARSER_duplicate_cert_record ( |
805 | const struct GNUNET_DNSPARSER_CertRecord *r) | 806 | const struct GNUNET_DNSPARSER_CertRecord *r) |
806 | { | 807 | { |
807 | struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup(r, sizeof(*r)); | 808 | struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof(*r)); |
808 | 809 | ||
809 | dup->certificate_data = GNUNET_strdup(r->certificate_data); | 810 | dup->certificate_data = GNUNET_strdup (r->certificate_data); |
810 | return dup; | 811 | return dup; |
811 | } | 812 | } |
812 | 813 | ||
@@ -818,11 +819,11 @@ GNUNET_DNSPARSER_duplicate_cert_record( | |||
818 | * @return the newly allocated record | 819 | * @return the newly allocated record |
819 | */ | 820 | */ |
820 | struct GNUNET_DNSPARSER_MxRecord * | 821 | struct GNUNET_DNSPARSER_MxRecord * |
821 | GNUNET_DNSPARSER_duplicate_mx_record(const struct GNUNET_DNSPARSER_MxRecord *r) | 822 | GNUNET_DNSPARSER_duplicate_mx_record (const struct GNUNET_DNSPARSER_MxRecord *r) |
822 | { | 823 | { |
823 | struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup(r, sizeof(*r)); | 824 | struct GNUNET_DNSPARSER_MxRecord *dup = GNUNET_memdup (r, sizeof(*r)); |
824 | 825 | ||
825 | dup->mxhost = GNUNET_strdup(r->mxhost); | 826 | dup->mxhost = GNUNET_strdup (r->mxhost); |
826 | return dup; | 827 | return dup; |
827 | } | 828 | } |
828 | 829 | ||
@@ -834,12 +835,12 @@ GNUNET_DNSPARSER_duplicate_mx_record(const struct GNUNET_DNSPARSER_MxRecord *r) | |||
834 | * @return the newly allocated record | 835 | * @return the newly allocated record |
835 | */ | 836 | */ |
836 | struct GNUNET_DNSPARSER_SrvRecord * | 837 | struct GNUNET_DNSPARSER_SrvRecord * |
837 | GNUNET_DNSPARSER_duplicate_srv_record( | 838 | GNUNET_DNSPARSER_duplicate_srv_record ( |
838 | const struct GNUNET_DNSPARSER_SrvRecord *r) | 839 | const struct GNUNET_DNSPARSER_SrvRecord *r) |
839 | { | 840 | { |
840 | struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup(r, sizeof(*r)); | 841 | struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof(*r)); |
841 | 842 | ||
842 | dup->target = GNUNET_strdup(r->target); | 843 | dup->target = GNUNET_strdup (r->target); |
843 | return dup; | 844 | return dup; |
844 | } | 845 | } |
845 | 846 | ||
@@ -850,21 +851,21 @@ GNUNET_DNSPARSER_duplicate_srv_record( | |||
850 | * @param p packet to free | 851 | * @param p packet to free |
851 | */ | 852 | */ |
852 | void | 853 | void |
853 | GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p) | 854 | GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p) |
854 | { | 855 | { |
855 | for (unsigned int i = 0; i < p->num_queries; i++) | 856 | for (unsigned int i = 0; i < p->num_queries; i++) |
856 | GNUNET_free_non_null(p->queries[i].name); | 857 | GNUNET_free_non_null (p->queries[i].name); |
857 | GNUNET_free_non_null(p->queries); | 858 | GNUNET_free_non_null (p->queries); |
858 | for (unsigned int i = 0; i < p->num_answers; i++) | 859 | for (unsigned int i = 0; i < p->num_answers; i++) |
859 | GNUNET_DNSPARSER_free_record(&p->answers[i]); | 860 | GNUNET_DNSPARSER_free_record (&p->answers[i]); |
860 | GNUNET_free_non_null(p->answers); | 861 | GNUNET_free_non_null (p->answers); |
861 | for (unsigned int i = 0; i < p->num_authority_records; i++) | 862 | for (unsigned int i = 0; i < p->num_authority_records; i++) |
862 | GNUNET_DNSPARSER_free_record(&p->authority_records[i]); | 863 | GNUNET_DNSPARSER_free_record (&p->authority_records[i]); |
863 | GNUNET_free_non_null(p->authority_records); | 864 | GNUNET_free_non_null (p->authority_records); |
864 | for (unsigned int i = 0; i < p->num_additional_records; i++) | 865 | for (unsigned int i = 0; i < p->num_additional_records; i++) |
865 | GNUNET_DNSPARSER_free_record(&p->additional_records[i]); | 866 | GNUNET_DNSPARSER_free_record (&p->additional_records[i]); |
866 | GNUNET_free_non_null(p->additional_records); | 867 | GNUNET_free_non_null (p->additional_records); |
867 | GNUNET_free(p); | 868 | GNUNET_free (p); |
868 | } | 869 | } |
869 | 870 | ||
870 | 871 | ||
@@ -885,10 +886,10 @@ GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p) | |||
885 | * #GNUNET_OK if @a name was added to @a dst | 886 | * #GNUNET_OK if @a name was added to @a dst |
886 | */ | 887 | */ |
887 | int | 888 | int |
888 | GNUNET_DNSPARSER_builder_add_name(char *dst, | 889 | GNUNET_DNSPARSER_builder_add_name (char *dst, |
889 | size_t dst_len, | 890 | size_t dst_len, |
890 | size_t *off, | 891 | size_t *off, |
891 | const char *name) | 892 | const char *name) |
892 | { | 893 | { |
893 | const char *dot; | 894 | const char *dot; |
894 | const char *idna_name; | 895 | const char *idna_name; |
@@ -902,47 +903,47 @@ GNUNET_DNSPARSER_builder_add_name(char *dst, | |||
902 | return GNUNET_SYSERR; | 903 | return GNUNET_SYSERR; |
903 | 904 | ||
904 | if (IDNA_SUCCESS != | 905 | if (IDNA_SUCCESS != |
905 | (rc = idna_to_ascii_8z(name, &idna_start, IDNA_ALLOW_UNASSIGNED))) | 906 | (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED))) |
906 | { | 907 | { |
907 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | 908 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
908 | _( | 909 | _ ( |
909 | "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"), | 910 | "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"), |
910 | name, | 911 | name, |
911 | idna_strerror(rc)); | 912 | idna_strerror (rc)); |
912 | return GNUNET_NO; | 913 | return GNUNET_NO; |
913 | } | 914 | } |
914 | idna_name = idna_start; | 915 | idna_name = idna_start; |
915 | start = *off; | 916 | start = *off; |
916 | if (start + strlen(idna_name) + 2 > dst_len) | 917 | if (start + strlen (idna_name) + 2 > dst_len) |
917 | goto fail; | 918 | goto fail; |
918 | pos = start; | 919 | pos = start; |
919 | do | 920 | do |
921 | { | ||
922 | dot = strchr (idna_name, '.'); | ||
923 | if (NULL == dot) | ||
924 | len = strlen (idna_name); | ||
925 | else | ||
926 | len = dot - idna_name; | ||
927 | if ((len >= 64) || (0 == len)) | ||
920 | { | 928 | { |
921 | dot = strchr(idna_name, '.'); | 929 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
922 | if (NULL == dot) | 930 | "Invalid DNS name `%s': label with %u characters encountered\n", |
923 | len = strlen(idna_name); | 931 | name, |
924 | else | 932 | (unsigned int) len); |
925 | len = dot - idna_name; | 933 | goto fail; /* label too long or empty */ |
926 | if ((len >= 64) || (0 == len)) | ||
927 | { | ||
928 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
929 | "Invalid DNS name `%s': label with %u characters encountered\n", | ||
930 | name, | ||
931 | (unsigned int)len); | ||
932 | goto fail; /* label too long or empty */ | ||
933 | } | ||
934 | dst[pos++] = (char)(uint8_t)len; | ||
935 | GNUNET_memcpy(&dst[pos], idna_name, len); | ||
936 | pos += len; | ||
937 | idna_name += len + 1; /* also skip dot */ | ||
938 | } | 934 | } |
935 | dst[pos++] = (char) (uint8_t) len; | ||
936 | GNUNET_memcpy (&dst[pos], idna_name, len); | ||
937 | pos += len; | ||
938 | idna_name += len + 1; /* also skip dot */ | ||
939 | } | ||
939 | while (NULL != dot); | 940 | while (NULL != dot); |
940 | dst[pos++] = '\0'; /* terminator */ | 941 | dst[pos++] = '\0'; /* terminator */ |
941 | *off = pos; | 942 | *off = pos; |
942 | free(idna_start); | 943 | free (idna_start); |
943 | return GNUNET_OK; | 944 | return GNUNET_OK; |
944 | fail: | 945 | fail: |
945 | free(idna_start); | 946 | free (idna_start); |
946 | return GNUNET_NO; | 947 | return GNUNET_NO; |
947 | } | 948 | } |
948 | 949 | ||
@@ -960,25 +961,25 @@ fail: | |||
960 | * #GNUNET_OK if @a query was added to @a dst | 961 | * #GNUNET_OK if @a query was added to @a dst |
961 | */ | 962 | */ |
962 | int | 963 | int |
963 | GNUNET_DNSPARSER_builder_add_query(char *dst, | 964 | GNUNET_DNSPARSER_builder_add_query (char *dst, |
964 | size_t dst_len, | 965 | size_t dst_len, |
965 | size_t *off, | 966 | size_t *off, |
966 | const struct GNUNET_DNSPARSER_Query *query) | 967 | const struct GNUNET_DNSPARSER_Query *query) |
967 | { | 968 | { |
968 | int ret; | 969 | int ret; |
969 | struct GNUNET_TUN_DnsQueryLine ql; | 970 | struct GNUNET_TUN_DnsQueryLine ql; |
970 | 971 | ||
971 | ret = GNUNET_DNSPARSER_builder_add_name(dst, | 972 | ret = GNUNET_DNSPARSER_builder_add_name (dst, |
972 | dst_len - | 973 | dst_len |
973 | sizeof( | 974 | - sizeof( |
974 | struct GNUNET_TUN_DnsQueryLine), | 975 | struct GNUNET_TUN_DnsQueryLine), |
975 | off, | 976 | off, |
976 | query->name); | 977 | query->name); |
977 | if (ret != GNUNET_OK) | 978 | if (ret != GNUNET_OK) |
978 | return ret; | 979 | return ret; |
979 | ql.type = htons(query->type); | 980 | ql.type = htons (query->type); |
980 | ql.dns_traffic_class = htons(query->dns_traffic_class); | 981 | ql.dns_traffic_class = htons (query->dns_traffic_class); |
981 | GNUNET_memcpy(&dst[*off], &ql, sizeof(ql)); | 982 | GNUNET_memcpy (&dst[*off], &ql, sizeof(ql)); |
982 | (*off) += sizeof(ql); | 983 | (*off) += sizeof(ql); |
983 | return GNUNET_OK; | 984 | return GNUNET_OK; |
984 | } | 985 | } |
@@ -997,19 +998,19 @@ GNUNET_DNSPARSER_builder_add_query(char *dst, | |||
997 | * #GNUNET_OK if @a mx was added to @a dst | 998 | * #GNUNET_OK if @a mx was added to @a dst |
998 | */ | 999 | */ |
999 | int | 1000 | int |
1000 | GNUNET_DNSPARSER_builder_add_mx(char *dst, | 1001 | GNUNET_DNSPARSER_builder_add_mx (char *dst, |
1001 | size_t dst_len, | 1002 | size_t dst_len, |
1002 | size_t *off, | 1003 | size_t *off, |
1003 | const struct GNUNET_DNSPARSER_MxRecord *mx) | 1004 | const struct GNUNET_DNSPARSER_MxRecord *mx) |
1004 | { | 1005 | { |
1005 | uint16_t mxpref; | 1006 | uint16_t mxpref; |
1006 | 1007 | ||
1007 | if (*off + sizeof(uint16_t) > dst_len) | 1008 | if (*off + sizeof(uint16_t) > dst_len) |
1008 | return GNUNET_NO; | 1009 | return GNUNET_NO; |
1009 | mxpref = htons(mx->preference); | 1010 | mxpref = htons (mx->preference); |
1010 | GNUNET_memcpy(&dst[*off], &mxpref, sizeof(mxpref)); | 1011 | GNUNET_memcpy (&dst[*off], &mxpref, sizeof(mxpref)); |
1011 | (*off) += sizeof(mxpref); | 1012 | (*off) += sizeof(mxpref); |
1012 | return GNUNET_DNSPARSER_builder_add_name(dst, dst_len, off, mx->mxhost); | 1013 | return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost); |
1013 | } | 1014 | } |
1014 | 1015 | ||
1015 | 1016 | ||
@@ -1026,7 +1027,7 @@ GNUNET_DNSPARSER_builder_add_mx(char *dst, | |||
1026 | * #GNUNET_OK if @a cert was added to @a dst | 1027 | * #GNUNET_OK if @a cert was added to @a dst |
1027 | */ | 1028 | */ |
1028 | int | 1029 | int |
1029 | GNUNET_DNSPARSER_builder_add_cert( | 1030 | GNUNET_DNSPARSER_builder_add_cert ( |
1030 | char *dst, | 1031 | char *dst, |
1031 | size_t dst_len, | 1032 | size_t dst_len, |
1032 | size_t *off, | 1033 | size_t *off, |
@@ -1039,22 +1040,22 @@ GNUNET_DNSPARSER_builder_add_cert( | |||
1039 | #pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" | 1040 | #pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" |
1040 | #endif | 1041 | #endif |
1041 | if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX)) | 1042 | if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX)) |
1042 | { | 1043 | { |
1043 | GNUNET_break(0); | 1044 | GNUNET_break (0); |
1044 | return GNUNET_SYSERR; | 1045 | return GNUNET_SYSERR; |
1045 | } | 1046 | } |
1046 | #ifdef __clang__ | 1047 | #ifdef __clang__ |
1047 | #pragma clang diagnostic pop | 1048 | #pragma clang diagnostic pop |
1048 | #endif | 1049 | #endif |
1049 | if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) + cert->certificate_size > | 1050 | if (*off + sizeof(struct GNUNET_TUN_DnsCertRecord) + cert->certificate_size > |
1050 | dst_len) | 1051 | dst_len) |
1051 | return GNUNET_NO; | 1052 | return GNUNET_NO; |
1052 | dcert.cert_type = htons((uint16_t)cert->cert_type); | 1053 | dcert.cert_type = htons ((uint16_t) cert->cert_type); |
1053 | dcert.cert_tag = htons((uint16_t)cert->cert_tag); | 1054 | dcert.cert_tag = htons ((uint16_t) cert->cert_tag); |
1054 | dcert.algorithm = (uint8_t)cert->algorithm; | 1055 | dcert.algorithm = (uint8_t) cert->algorithm; |
1055 | GNUNET_memcpy(&dst[*off], &dcert, sizeof(dcert)); | 1056 | GNUNET_memcpy (&dst[*off], &dcert, sizeof(dcert)); |
1056 | (*off) += sizeof(dcert); | 1057 | (*off) += sizeof(dcert); |
1057 | GNUNET_memcpy(&dst[*off], cert->certificate_data, cert->certificate_size); | 1058 | GNUNET_memcpy (&dst[*off], cert->certificate_data, cert->certificate_size); |
1058 | (*off) += cert->certificate_size; | 1059 | (*off) += cert->certificate_size; |
1059 | return GNUNET_OK; | 1060 | return GNUNET_OK; |
1060 | } | 1061 | } |
@@ -1073,29 +1074,29 @@ GNUNET_DNSPARSER_builder_add_cert( | |||
1073 | * #GNUNET_OK if @a soa was added to @a dst | 1074 | * #GNUNET_OK if @a soa was added to @a dst |
1074 | */ | 1075 | */ |
1075 | int | 1076 | int |
1076 | GNUNET_DNSPARSER_builder_add_soa(char *dst, | 1077 | GNUNET_DNSPARSER_builder_add_soa (char *dst, |
1077 | size_t dst_len, | 1078 | size_t dst_len, |
1078 | size_t *off, | 1079 | size_t *off, |
1079 | const struct GNUNET_DNSPARSER_SoaRecord *soa) | 1080 | const struct GNUNET_DNSPARSER_SoaRecord *soa) |
1080 | { | 1081 | { |
1081 | struct GNUNET_TUN_DnsSoaRecord sd; | 1082 | struct GNUNET_TUN_DnsSoaRecord sd; |
1082 | int ret; | 1083 | int ret; |
1083 | 1084 | ||
1084 | if ((GNUNET_OK != | 1085 | if ((GNUNET_OK != |
1085 | (ret = | 1086 | (ret = |
1086 | GNUNET_DNSPARSER_builder_add_name(dst, dst_len, off, soa->mname))) || | 1087 | GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->mname))) || |
1087 | (GNUNET_OK != | 1088 | (GNUNET_OK != |
1088 | (ret = | 1089 | (ret = |
1089 | GNUNET_DNSPARSER_builder_add_name(dst, dst_len, off, soa->rname)))) | 1090 | GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->rname)))) |
1090 | return ret; | 1091 | return ret; |
1091 | if (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > dst_len) | 1092 | if (*off + sizeof(struct GNUNET_TUN_DnsSoaRecord) > dst_len) |
1092 | return GNUNET_NO; | 1093 | return GNUNET_NO; |
1093 | sd.serial = htonl(soa->serial); | 1094 | sd.serial = htonl (soa->serial); |
1094 | sd.refresh = htonl(soa->refresh); | 1095 | sd.refresh = htonl (soa->refresh); |
1095 | sd.retry = htonl(soa->retry); | 1096 | sd.retry = htonl (soa->retry); |
1096 | sd.expire = htonl(soa->expire); | 1097 | sd.expire = htonl (soa->expire); |
1097 | sd.minimum = htonl(soa->minimum_ttl); | 1098 | sd.minimum = htonl (soa->minimum_ttl); |
1098 | GNUNET_memcpy(&dst[*off], &sd, sizeof(sd)); | 1099 | GNUNET_memcpy (&dst[*off], &sd, sizeof(sd)); |
1099 | (*off) += sizeof(sd); | 1100 | (*off) += sizeof(sd); |
1100 | return GNUNET_OK; | 1101 | return GNUNET_OK; |
1101 | } | 1102 | } |
@@ -1114,24 +1115,24 @@ GNUNET_DNSPARSER_builder_add_soa(char *dst, | |||
1114 | * #GNUNET_OK if @a srv was added to @a dst | 1115 | * #GNUNET_OK if @a srv was added to @a dst |
1115 | */ | 1116 | */ |
1116 | int | 1117 | int |
1117 | GNUNET_DNSPARSER_builder_add_srv(char *dst, | 1118 | GNUNET_DNSPARSER_builder_add_srv (char *dst, |
1118 | size_t dst_len, | 1119 | size_t dst_len, |
1119 | size_t *off, | 1120 | size_t *off, |
1120 | const struct GNUNET_DNSPARSER_SrvRecord *srv) | 1121 | const struct GNUNET_DNSPARSER_SrvRecord *srv) |
1121 | { | 1122 | { |
1122 | struct GNUNET_TUN_DnsSrvRecord sd; | 1123 | struct GNUNET_TUN_DnsSrvRecord sd; |
1123 | int ret; | 1124 | int ret; |
1124 | 1125 | ||
1125 | if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > dst_len) | 1126 | if (*off + sizeof(struct GNUNET_TUN_DnsSrvRecord) > dst_len) |
1126 | return GNUNET_NO; | 1127 | return GNUNET_NO; |
1127 | sd.prio = htons(srv->priority); | 1128 | sd.prio = htons (srv->priority); |
1128 | sd.weight = htons(srv->weight); | 1129 | sd.weight = htons (srv->weight); |
1129 | sd.port = htons(srv->port); | 1130 | sd.port = htons (srv->port); |
1130 | GNUNET_memcpy(&dst[*off], &sd, sizeof(sd)); | 1131 | GNUNET_memcpy (&dst[*off], &sd, sizeof(sd)); |
1131 | (*off) += sizeof(sd); | 1132 | (*off) += sizeof(sd); |
1132 | if (GNUNET_OK != | 1133 | if (GNUNET_OK != |
1133 | (ret = | 1134 | (ret = |
1134 | GNUNET_DNSPARSER_builder_add_name(dst, dst_len, off, srv->target))) | 1135 | GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, srv->target))) |
1135 | return ret; | 1136 | return ret; |
1136 | return GNUNET_OK; | 1137 | return GNUNET_OK; |
1137 | } | 1138 | } |
@@ -1150,10 +1151,10 @@ GNUNET_DNSPARSER_builder_add_srv(char *dst, | |||
1150 | * #GNUNET_OK if @a record was added to @a dst | 1151 | * #GNUNET_OK if @a record was added to @a dst |
1151 | */ | 1152 | */ |
1152 | static int | 1153 | static int |
1153 | add_record(char *dst, | 1154 | add_record (char *dst, |
1154 | size_t dst_len, | 1155 | size_t dst_len, |
1155 | size_t *off, | 1156 | size_t *off, |
1156 | const struct GNUNET_DNSPARSER_Record *record) | 1157 | const struct GNUNET_DNSPARSER_Record *record) |
1157 | { | 1158 | { |
1158 | int ret; | 1159 | int ret; |
1159 | size_t start; | 1160 | size_t start; |
@@ -1161,78 +1162,78 @@ add_record(char *dst, | |||
1161 | struct GNUNET_TUN_DnsRecordLine rl; | 1162 | struct GNUNET_TUN_DnsRecordLine rl; |
1162 | 1163 | ||
1163 | start = *off; | 1164 | start = *off; |
1164 | ret = GNUNET_DNSPARSER_builder_add_name(dst, | 1165 | ret = GNUNET_DNSPARSER_builder_add_name (dst, |
1165 | dst_len - | 1166 | dst_len |
1166 | sizeof( | 1167 | - sizeof( |
1167 | struct GNUNET_TUN_DnsRecordLine), | 1168 | struct GNUNET_TUN_DnsRecordLine), |
1168 | off, | 1169 | off, |
1169 | record->name); | 1170 | record->name); |
1170 | if (GNUNET_OK != ret) | 1171 | if (GNUNET_OK != ret) |
1171 | return ret; | 1172 | return ret; |
1172 | /* '*off' is now the position where we will need to write the record line */ | 1173 | /* '*off' is now the position where we will need to write the record line */ |
1173 | 1174 | ||
1174 | pos = *off + sizeof(struct GNUNET_TUN_DnsRecordLine); | 1175 | pos = *off + sizeof(struct GNUNET_TUN_DnsRecordLine); |
1175 | switch (record->type) | 1176 | switch (record->type) |
1177 | { | ||
1178 | case GNUNET_DNSPARSER_TYPE_MX: | ||
1179 | ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx); | ||
1180 | break; | ||
1181 | |||
1182 | case GNUNET_DNSPARSER_TYPE_CERT: | ||
1183 | ret = | ||
1184 | GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert); | ||
1185 | break; | ||
1186 | |||
1187 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
1188 | ret = | ||
1189 | GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa); | ||
1190 | break; | ||
1191 | |||
1192 | case GNUNET_DNSPARSER_TYPE_NS: | ||
1193 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
1194 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
1195 | ret = GNUNET_DNSPARSER_builder_add_name (dst, | ||
1196 | dst_len, | ||
1197 | &pos, | ||
1198 | record->data.hostname); | ||
1199 | break; | ||
1200 | |||
1201 | case GNUNET_DNSPARSER_TYPE_SRV: | ||
1202 | ret = | ||
1203 | GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv); | ||
1204 | break; | ||
1205 | |||
1206 | default: | ||
1207 | if (pos + record->data.raw.data_len > dst_len) | ||
1176 | { | 1208 | { |
1177 | case GNUNET_DNSPARSER_TYPE_MX: | 1209 | ret = GNUNET_NO; |
1178 | ret = GNUNET_DNSPARSER_builder_add_mx(dst, dst_len, &pos, record->data.mx); | ||
1179 | break; | ||
1180 | |||
1181 | case GNUNET_DNSPARSER_TYPE_CERT: | ||
1182 | ret = | ||
1183 | GNUNET_DNSPARSER_builder_add_cert(dst, dst_len, &pos, record->data.cert); | ||
1184 | break; | ||
1185 | |||
1186 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
1187 | ret = | ||
1188 | GNUNET_DNSPARSER_builder_add_soa(dst, dst_len, &pos, record->data.soa); | ||
1189 | break; | ||
1190 | |||
1191 | case GNUNET_DNSPARSER_TYPE_NS: | ||
1192 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
1193 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
1194 | ret = GNUNET_DNSPARSER_builder_add_name(dst, | ||
1195 | dst_len, | ||
1196 | &pos, | ||
1197 | record->data.hostname); | ||
1198 | break; | ||
1199 | |||
1200 | case GNUNET_DNSPARSER_TYPE_SRV: | ||
1201 | ret = | ||
1202 | GNUNET_DNSPARSER_builder_add_srv(dst, dst_len, &pos, record->data.srv); | ||
1203 | break; | ||
1204 | |||
1205 | default: | ||
1206 | if (pos + record->data.raw.data_len > dst_len) | ||
1207 | { | ||
1208 | ret = GNUNET_NO; | ||
1209 | break; | ||
1210 | } | ||
1211 | GNUNET_memcpy(&dst[pos], record->data.raw.data, record->data.raw.data_len); | ||
1212 | pos += record->data.raw.data_len; | ||
1213 | ret = GNUNET_OK; | ||
1214 | break; | 1210 | break; |
1215 | } | 1211 | } |
1212 | GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len); | ||
1213 | pos += record->data.raw.data_len; | ||
1214 | ret = GNUNET_OK; | ||
1215 | break; | ||
1216 | } | ||
1216 | if (GNUNET_OK != ret) | 1217 | if (GNUNET_OK != ret) |
1217 | { | 1218 | { |
1218 | *off = start; | 1219 | *off = start; |
1219 | return GNUNET_NO; | 1220 | return GNUNET_NO; |
1220 | } | 1221 | } |
1221 | 1222 | ||
1222 | if (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)) > UINT16_MAX) | 1223 | if (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)) > UINT16_MAX) |
1223 | { | 1224 | { |
1224 | /* record data too long */ | 1225 | /* record data too long */ |
1225 | *off = start; | 1226 | *off = start; |
1226 | return GNUNET_NO; | 1227 | return GNUNET_NO; |
1227 | } | 1228 | } |
1228 | rl.type = htons(record->type); | 1229 | rl.type = htons (record->type); |
1229 | rl.dns_traffic_class = htons(record->dns_traffic_class); | 1230 | rl.dns_traffic_class = htons (record->dns_traffic_class); |
1230 | rl.ttl = htonl( | 1231 | rl.ttl = htonl ( |
1231 | GNUNET_TIME_absolute_get_remaining(record->expiration_time).rel_value_us / | 1232 | GNUNET_TIME_absolute_get_remaining (record->expiration_time).rel_value_us |
1232 | 1000LL / 1000LL); /* in seconds */ | 1233 | / 1000LL / 1000LL); /* in seconds */ |
1233 | rl.data_len = htons( | 1234 | rl.data_len = htons ( |
1234 | (uint16_t)(pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)))); | 1235 | (uint16_t) (pos - (*off + sizeof(struct GNUNET_TUN_DnsRecordLine)))); |
1235 | GNUNET_memcpy(&dst[*off], &rl, sizeof(struct GNUNET_TUN_DnsRecordLine)); | 1236 | GNUNET_memcpy (&dst[*off], &rl, sizeof(struct GNUNET_TUN_DnsRecordLine)); |
1236 | *off = pos; | 1237 | *off = pos; |
1237 | return GNUNET_OK; | 1238 | return GNUNET_OK; |
1238 | } | 1239 | } |
@@ -1253,10 +1254,10 @@ add_record(char *dst, | |||
1253 | * #GNUNET_OK if @a p was packed completely into @a buf | 1254 | * #GNUNET_OK if @a p was packed completely into @a buf |
1254 | */ | 1255 | */ |
1255 | int | 1256 | int |
1256 | GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, | 1257 | GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p, |
1257 | uint16_t max, | 1258 | uint16_t max, |
1258 | char **buf, | 1259 | char **buf, |
1259 | size_t *buf_length) | 1260 | size_t *buf_length) |
1260 | { | 1261 | { |
1261 | struct GNUNET_TUN_DnsHeader dns; | 1262 | struct GNUNET_TUN_DnsHeader dns; |
1262 | size_t off; | 1263 | size_t off; |
@@ -1270,72 +1271,72 @@ GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, | |||
1270 | return GNUNET_SYSERR; | 1271 | return GNUNET_SYSERR; |
1271 | dns.id = p->id; | 1272 | dns.id = p->id; |
1272 | dns.flags = p->flags; | 1273 | dns.flags = p->flags; |
1273 | dns.query_count = htons(p->num_queries); | 1274 | dns.query_count = htons (p->num_queries); |
1274 | dns.answer_rcount = htons(p->num_answers); | 1275 | dns.answer_rcount = htons (p->num_answers); |
1275 | dns.authority_rcount = htons(p->num_authority_records); | 1276 | dns.authority_rcount = htons (p->num_authority_records); |
1276 | dns.additional_rcount = htons(p->num_additional_records); | 1277 | dns.additional_rcount = htons (p->num_additional_records); |
1277 | 1278 | ||
1278 | off = sizeof(struct GNUNET_TUN_DnsHeader); | 1279 | off = sizeof(struct GNUNET_TUN_DnsHeader); |
1279 | trc = GNUNET_NO; | 1280 | trc = GNUNET_NO; |
1280 | for (unsigned int i = 0; i < p->num_queries; i++) | 1281 | for (unsigned int i = 0; i < p->num_queries; i++) |
1282 | { | ||
1283 | ret = GNUNET_DNSPARSER_builder_add_query (tmp, | ||
1284 | sizeof(tmp), | ||
1285 | &off, | ||
1286 | &p->queries[i]); | ||
1287 | if (GNUNET_SYSERR == ret) | ||
1288 | return GNUNET_SYSERR; | ||
1289 | if (GNUNET_NO == ret) | ||
1281 | { | 1290 | { |
1282 | ret = GNUNET_DNSPARSER_builder_add_query(tmp, | 1291 | dns.query_count = htons ((uint16_t) (i - 1)); |
1283 | sizeof(tmp), | 1292 | trc = GNUNET_YES; |
1284 | &off, | 1293 | break; |
1285 | &p->queries[i]); | ||
1286 | if (GNUNET_SYSERR == ret) | ||
1287 | return GNUNET_SYSERR; | ||
1288 | if (GNUNET_NO == ret) | ||
1289 | { | ||
1290 | dns.query_count = htons((uint16_t)(i - 1)); | ||
1291 | trc = GNUNET_YES; | ||
1292 | break; | ||
1293 | } | ||
1294 | } | 1294 | } |
1295 | } | ||
1295 | for (unsigned int i = 0; i < p->num_answers; i++) | 1296 | for (unsigned int i = 0; i < p->num_answers; i++) |
1297 | { | ||
1298 | ret = add_record (tmp, sizeof(tmp), &off, &p->answers[i]); | ||
1299 | if (GNUNET_SYSERR == ret) | ||
1300 | return GNUNET_SYSERR; | ||
1301 | if (GNUNET_NO == ret) | ||
1296 | { | 1302 | { |
1297 | ret = add_record(tmp, sizeof(tmp), &off, &p->answers[i]); | 1303 | dns.answer_rcount = htons ((uint16_t) (i - 1)); |
1298 | if (GNUNET_SYSERR == ret) | 1304 | trc = GNUNET_YES; |
1299 | return GNUNET_SYSERR; | 1305 | break; |
1300 | if (GNUNET_NO == ret) | ||
1301 | { | ||
1302 | dns.answer_rcount = htons((uint16_t)(i - 1)); | ||
1303 | trc = GNUNET_YES; | ||
1304 | break; | ||
1305 | } | ||
1306 | } | 1306 | } |
1307 | } | ||
1307 | for (unsigned int i = 0; i < p->num_authority_records; i++) | 1308 | for (unsigned int i = 0; i < p->num_authority_records; i++) |
1309 | { | ||
1310 | ret = add_record (tmp, sizeof(tmp), &off, &p->authority_records[i]); | ||
1311 | if (GNUNET_SYSERR == ret) | ||
1312 | return GNUNET_SYSERR; | ||
1313 | if (GNUNET_NO == ret) | ||
1308 | { | 1314 | { |
1309 | ret = add_record(tmp, sizeof(tmp), &off, &p->authority_records[i]); | 1315 | dns.authority_rcount = htons ((uint16_t) (i - 1)); |
1310 | if (GNUNET_SYSERR == ret) | 1316 | trc = GNUNET_YES; |
1311 | return GNUNET_SYSERR; | 1317 | break; |
1312 | if (GNUNET_NO == ret) | ||
1313 | { | ||
1314 | dns.authority_rcount = htons((uint16_t)(i - 1)); | ||
1315 | trc = GNUNET_YES; | ||
1316 | break; | ||
1317 | } | ||
1318 | } | 1318 | } |
1319 | } | ||
1319 | for (unsigned int i = 0; i < p->num_additional_records; i++) | 1320 | for (unsigned int i = 0; i < p->num_additional_records; i++) |
1321 | { | ||
1322 | ret = add_record (tmp, sizeof(tmp), &off, &p->additional_records[i]); | ||
1323 | if (GNUNET_SYSERR == ret) | ||
1324 | return GNUNET_SYSERR; | ||
1325 | if (GNUNET_NO == ret) | ||
1320 | { | 1326 | { |
1321 | ret = add_record(tmp, sizeof(tmp), &off, &p->additional_records[i]); | 1327 | dns.additional_rcount = htons (i - 1); |
1322 | if (GNUNET_SYSERR == ret) | 1328 | trc = GNUNET_YES; |
1323 | return GNUNET_SYSERR; | 1329 | break; |
1324 | if (GNUNET_NO == ret) | ||
1325 | { | ||
1326 | dns.additional_rcount = htons(i - 1); | ||
1327 | trc = GNUNET_YES; | ||
1328 | break; | ||
1329 | } | ||
1330 | } | 1330 | } |
1331 | } | ||
1331 | 1332 | ||
1332 | if (GNUNET_YES == trc) | 1333 | if (GNUNET_YES == trc) |
1333 | dns.flags.message_truncated = 1; | 1334 | dns.flags.message_truncated = 1; |
1334 | GNUNET_memcpy(tmp, &dns, sizeof(struct GNUNET_TUN_DnsHeader)); | 1335 | GNUNET_memcpy (tmp, &dns, sizeof(struct GNUNET_TUN_DnsHeader)); |
1335 | 1336 | ||
1336 | *buf = GNUNET_malloc(off); | 1337 | *buf = GNUNET_malloc (off); |
1337 | *buf_length = off; | 1338 | *buf_length = off; |
1338 | GNUNET_memcpy(*buf, tmp, off); | 1339 | GNUNET_memcpy (*buf, tmp, off); |
1339 | if (GNUNET_YES == trc) | 1340 | if (GNUNET_YES == trc) |
1340 | return GNUNET_NO; | 1341 | return GNUNET_NO; |
1341 | return GNUNET_OK; | 1342 | return GNUNET_OK; |
@@ -1350,16 +1351,16 @@ GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, | |||
1350 | * @return HEX string (lower case) | 1351 | * @return HEX string (lower case) |
1351 | */ | 1352 | */ |
1352 | char * | 1353 | char * |
1353 | GNUNET_DNSPARSER_bin_to_hex(const void *data, size_t data_size) | 1354 | GNUNET_DNSPARSER_bin_to_hex (const void *data, size_t data_size) |
1354 | { | 1355 | { |
1355 | char *ret; | 1356 | char *ret; |
1356 | size_t off; | 1357 | size_t off; |
1357 | const uint8_t *idata; | 1358 | const uint8_t *idata; |
1358 | 1359 | ||
1359 | idata = data; | 1360 | idata = data; |
1360 | ret = GNUNET_malloc(data_size * 2 + 1); | 1361 | ret = GNUNET_malloc (data_size * 2 + 1); |
1361 | for (off = 0; off < data_size; off++) | 1362 | for (off = 0; off < data_size; off++) |
1362 | sprintf(&ret[off * 2], "%02x", idata[off]); | 1363 | sprintf (&ret[off * 2], "%02x", idata[off]); |
1363 | return ret; | 1364 | return ret; |
1364 | } | 1365 | } |
1365 | 1366 | ||
@@ -1373,7 +1374,7 @@ GNUNET_DNSPARSER_bin_to_hex(const void *data, size_t data_size) | |||
1373 | * @return number of bytes written to data | 1374 | * @return number of bytes written to data |
1374 | */ | 1375 | */ |
1375 | size_t | 1376 | size_t |
1376 | GNUNET_DNSPARSER_hex_to_bin(const char *hex, void *data) | 1377 | GNUNET_DNSPARSER_hex_to_bin (const char *hex, void *data) |
1377 | { | 1378 | { |
1378 | size_t data_size; | 1379 | size_t data_size; |
1379 | size_t off; | 1380 | size_t off; |
@@ -1381,17 +1382,17 @@ GNUNET_DNSPARSER_hex_to_bin(const char *hex, void *data) | |||
1381 | unsigned int h; | 1382 | unsigned int h; |
1382 | char in[3]; | 1383 | char in[3]; |
1383 | 1384 | ||
1384 | data_size = strlen(hex) / 2; | 1385 | data_size = strlen (hex) / 2; |
1385 | idata = data; | 1386 | idata = data; |
1386 | in[2] = '\0'; | 1387 | in[2] = '\0'; |
1387 | for (off = 0; off < data_size; off++) | 1388 | for (off = 0; off < data_size; off++) |
1388 | { | 1389 | { |
1389 | in[0] = tolower((unsigned char)hex[off * 2]); | 1390 | in[0] = tolower ((unsigned char) hex[off * 2]); |
1390 | in[1] = tolower((unsigned char)hex[off * 2 + 1]); | 1391 | in[1] = tolower ((unsigned char) hex[off * 2 + 1]); |
1391 | if (1 != sscanf(in, "%x", &h)) | 1392 | if (1 != sscanf (in, "%x", &h)) |
1392 | return off; | 1393 | return off; |
1393 | idata[off] = (uint8_t)h; | 1394 | idata[off] = (uint8_t) h; |
1394 | } | 1395 | } |
1395 | return off; | 1396 | return off; |
1396 | } | 1397 | } |
1397 | 1398 | ||