aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-service-gns_interceptor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-service-gns_interceptor.c')
-rw-r--r--src/gns/gnunet-service-gns_interceptor.c429
1 files changed, 217 insertions, 212 deletions
diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c
index d5a84f6a0..e56aaef47 100644
--- a/src/gns/gnunet-service-gns_interceptor.c
+++ b/src/gns/gnunet-service-gns_interceptor.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20/** 20/**
21 * @file gns/gnunet-service-gns_interceptor.c 21 * @file gns/gnunet-service-gns_interceptor.c
22 * @brief GNUnet GNS interceptor logic 22 * @brief GNUnet GNS interceptor logic
@@ -37,9 +37,7 @@
37 * Handle to a DNS intercepted 37 * Handle to a DNS intercepted
38 * reslution request 38 * reslution request
39 */ 39 */
40struct InterceptLookupHandle 40struct InterceptLookupHandle {
41{
42
43 /** 41 /**
44 * We keep these in a DLL. 42 * We keep these in a DLL.
45 */ 43 */
@@ -64,7 +62,6 @@ struct InterceptLookupHandle
64 * Handle for the lookup operation. 62 * Handle for the lookup operation.
65 */ 63 */
66 struct GNS_ResolverHandle *lookup; 64 struct GNS_ResolverHandle *lookup;
67
68}; 65};
69 66
70 67
@@ -92,8 +89,8 @@ static struct InterceptLookupHandle *ilh_tail;
92 * @param rd the record data 89 * @param rd the record data
93 */ 90 */
94static void 91static void
95reply_to_dns (void *cls, uint32_t rd_count, 92reply_to_dns(void *cls, uint32_t rd_count,
96 const struct GNUNET_GNSRECORD_Data *rd) 93 const struct GNUNET_GNSRECORD_Data *rd)
97{ 94{
98 struct InterceptLookupHandle *ilh = cls; 95 struct InterceptLookupHandle *ilh = cls;
99 struct GNUNET_DNSPARSER_Packet *packet = ilh->packet; 96 struct GNUNET_DNSPARSER_Packet *packet = ilh->packet;
@@ -109,7 +106,7 @@ reply_to_dns (void *cls, uint32_t rd_count,
109 106
110 /* Put records in the DNS packet */ 107 /* Put records in the DNS packet */
111 num_answers = 0; 108 num_answers = 0;
112 for (i=0; i < rd_count; i++) 109 for (i = 0; i < rd_count; i++)
113 if (rd[i].record_type == query->type) 110 if (rd[i].record_type == query->type)
114 num_answers++; 111 num_answers++;
115 skip_answers = 0; 112 skip_answers = 0;
@@ -124,123 +121,131 @@ reply_to_dns (void *cls, uint32_t rd_count,
124 /* FIXME: need to handle #GNUNET_GNSRECORD_RF_SHADOW_RECORD option 121 /* FIXME: need to handle #GNUNET_GNSRECORD_RF_SHADOW_RECORD option
125 (by ignoring records where this flag is set if there is any 122 (by ignoring records where this flag is set if there is any
126 other record of that type in the result set) */ 123 other record of that type in the result set) */
127 for (i=0; i < rd_count; i++) 124 for (i = 0; i < rd_count; i++)
128 {
129 if (rd[i].record_type == query->type)
130 { 125 {
131 answer_records[i - skip_answers].name = query->name; 126 if (rd[i].record_type == query->type)
132 answer_records[i - skip_answers].type = rd[i].record_type; 127 {
133 switch(rd[i].record_type) 128 answer_records[i - skip_answers].name = query->name;
134 { 129 answer_records[i - skip_answers].type = rd[i].record_type;
135 case GNUNET_DNSPARSER_TYPE_NS: 130 switch (rd[i].record_type)
136 case GNUNET_DNSPARSER_TYPE_CNAME: 131 {
137 case GNUNET_DNSPARSER_TYPE_PTR: 132 case GNUNET_DNSPARSER_TYPE_NS:
138 answer_records[i - skip_answers].data.hostname 133 case GNUNET_DNSPARSER_TYPE_CNAME:
139 = GNUNET_DNSPARSER_parse_name (rd[i].data, 134 case GNUNET_DNSPARSER_TYPE_PTR:
140 rd[i].data_size, 135 answer_records[i - skip_answers].data.hostname
141 &off); 136 = GNUNET_DNSPARSER_parse_name(rd[i].data,
142 if ( (off != rd[i].data_size) || 137 rd[i].data_size,
143 (NULL == answer_records[i].data.hostname) ) 138 &off);
144 { 139 if ((off != rd[i].data_size) ||
145 GNUNET_break_op (0); 140 (NULL == answer_records[i].data.hostname))
146 skip_answers++; 141 {
147 } 142 GNUNET_break_op(0);
148 break; 143 skip_answers++;
149 case GNUNET_DNSPARSER_TYPE_SOA: 144 }
150 answer_records[i - skip_answers].data.soa 145 break;
151 = GNUNET_DNSPARSER_parse_soa (rd[i].data, 146
152 rd[i].data_size, 147 case GNUNET_DNSPARSER_TYPE_SOA:
153 &off); 148 answer_records[i - skip_answers].data.soa
154 if ( (off != rd[i].data_size) || 149 = GNUNET_DNSPARSER_parse_soa(rd[i].data,
155 (NULL == answer_records[i].data.soa) ) 150 rd[i].data_size,
156 { 151 &off);
157 GNUNET_break_op (0); 152 if ((off != rd[i].data_size) ||
158 skip_answers++; 153 (NULL == answer_records[i].data.soa))
159 } 154 {
160 break; 155 GNUNET_break_op(0);
161 case GNUNET_DNSPARSER_TYPE_SRV: 156 skip_answers++;
162 /* FIXME: SRV is not yet supported */ 157 }
163 skip_answers++; 158 break;
164 break; 159
165 case GNUNET_DNSPARSER_TYPE_MX: 160 case GNUNET_DNSPARSER_TYPE_SRV:
166 answer_records[i - skip_answers].data.mx 161 /* FIXME: SRV is not yet supported */
167 = GNUNET_DNSPARSER_parse_mx (rd[i].data, 162 skip_answers++;
168 rd[i].data_size, 163 break;
169 &off); 164
170 if ( (off != rd[i].data_size) || 165 case GNUNET_DNSPARSER_TYPE_MX:
171 (NULL == answer_records[i].data.hostname) ) 166 answer_records[i - skip_answers].data.mx
172 { 167 = GNUNET_DNSPARSER_parse_mx(rd[i].data,
173 GNUNET_break_op (0); 168 rd[i].data_size,
174 skip_answers++; 169 &off);
175 } 170 if ((off != rd[i].data_size) ||
176 break; 171 (NULL == answer_records[i].data.hostname))
177 default: 172 {
178 answer_records[i - skip_answers].data.raw.data_len = rd[i].data_size; 173 GNUNET_break_op(0);
179 answer_records[i - skip_answers].data.raw.data = (char*)rd[i].data; 174 skip_answers++;
180 break; 175 }
181 } 176 break;
182 GNUNET_break (0 == (rd[i - skip_answers].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)); 177
183 answer_records[i - skip_answers].expiration_time.abs_value_us = rd[i].expiration_time; 178 default:
184 answer_records[i - skip_answers].dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET; 179 answer_records[i - skip_answers].data.raw.data_len = rd[i].data_size;
185 } 180 answer_records[i - skip_answers].data.raw.data = (char*)rd[i].data;
186 else 181 break;
187 { 182 }
188 additional_records[i - skip_additional].name = query->name; 183 GNUNET_break(0 == (rd[i - skip_answers].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION));
189 additional_records[i - skip_additional].type = rd[i].record_type; 184 answer_records[i - skip_answers].expiration_time.abs_value_us = rd[i].expiration_time;
190 switch(rd[i].record_type) 185 answer_records[i - skip_answers].dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
191 { 186 }
192 case GNUNET_DNSPARSER_TYPE_NS: 187 else
193 case GNUNET_DNSPARSER_TYPE_CNAME: 188 {
194 case GNUNET_DNSPARSER_TYPE_PTR: 189 additional_records[i - skip_additional].name = query->name;
195 additional_records[i - skip_additional].data.hostname 190 additional_records[i - skip_additional].type = rd[i].record_type;
196 = GNUNET_DNSPARSER_parse_name (rd[i].data, 191 switch (rd[i].record_type)
197 rd[i].data_size, 192 {
198 &off); 193 case GNUNET_DNSPARSER_TYPE_NS:
199 if ( (off != rd[i].data_size) || 194 case GNUNET_DNSPARSER_TYPE_CNAME:
200 (NULL == additional_records[i].data.hostname) ) 195 case GNUNET_DNSPARSER_TYPE_PTR:
201 { 196 additional_records[i - skip_additional].data.hostname
202 GNUNET_break_op (0); 197 = GNUNET_DNSPARSER_parse_name(rd[i].data,
203 skip_additional++; 198 rd[i].data_size,
204 } 199 &off);
205 break; 200 if ((off != rd[i].data_size) ||
206 case GNUNET_DNSPARSER_TYPE_SOA: 201 (NULL == additional_records[i].data.hostname))
207 additional_records[i - skip_additional].data.soa 202 {
208 = GNUNET_DNSPARSER_parse_soa (rd[i].data, 203 GNUNET_break_op(0);
209 rd[i].data_size, 204 skip_additional++;
210 &off); 205 }
211 if ( (off != rd[i].data_size) || 206 break;
212 (NULL == additional_records[i].data.hostname) ) 207
213 { 208 case GNUNET_DNSPARSER_TYPE_SOA:
214 GNUNET_break_op (0); 209 additional_records[i - skip_additional].data.soa
215 skip_additional++; 210 = GNUNET_DNSPARSER_parse_soa(rd[i].data,
216 } 211 rd[i].data_size,
217 break; 212 &off);
218 case GNUNET_DNSPARSER_TYPE_MX: 213 if ((off != rd[i].data_size) ||
219 additional_records[i - skip_additional].data.mx 214 (NULL == additional_records[i].data.hostname))
220 = GNUNET_DNSPARSER_parse_mx (rd[i].data, 215 {
221 rd[i].data_size, 216 GNUNET_break_op(0);
222 &off); 217 skip_additional++;
223 if ( (off != rd[i].data_size) || 218 }
224 (NULL == additional_records[i].data.hostname) ) 219 break;
225 { 220
226 GNUNET_break_op (0); 221 case GNUNET_DNSPARSER_TYPE_MX:
227 skip_additional++; 222 additional_records[i - skip_additional].data.mx
228 } 223 = GNUNET_DNSPARSER_parse_mx(rd[i].data,
229 break; 224 rd[i].data_size,
230 case GNUNET_DNSPARSER_TYPE_SRV: 225 &off);
231 /* FIXME: SRV is not yet supported */ 226 if ((off != rd[i].data_size) ||
232 skip_answers++; 227 (NULL == additional_records[i].data.hostname))
233 break; 228 {
234 default: 229 GNUNET_break_op(0);
235 additional_records[i - skip_additional].data.raw.data_len = rd[i].data_size; 230 skip_additional++;
236 additional_records[i - skip_additional].data.raw.data = (char*)rd[i].data; 231 }
237 break; 232 break;
238 } 233
239 GNUNET_break (0 == (rd[i - skip_additional].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)); 234 case GNUNET_DNSPARSER_TYPE_SRV:
240 additional_records[i - skip_additional].expiration_time.abs_value_us = rd[i].expiration_time; 235 /* FIXME: SRV is not yet supported */
241 additional_records[i - skip_additional].dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET; 236 skip_answers++;
237 break;
238
239 default:
240 additional_records[i - skip_additional].data.raw.data_len = rd[i].data_size;
241 additional_records[i - skip_additional].data.raw.data = (char*)rd[i].data;
242 break;
243 }
244 GNUNET_break(0 == (rd[i - skip_additional].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION));
245 additional_records[i - skip_additional].expiration_time.abs_value_us = rd[i].expiration_time;
246 additional_records[i - skip_additional].dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
247 }
242 } 248 }
243 }
244 packet->num_answers = num_answers - skip_answers; 249 packet->num_answers = num_answers - skip_answers;
245 packet->num_additional_records = rd_count - num_answers - skip_additional; 250 packet->num_additional_records = rd_count - num_answers - skip_additional;
246 packet->flags.authoritative_answer = 1; 251 packet->flags.authoritative_answer = 1;
@@ -249,32 +254,32 @@ reply_to_dns (void *cls, uint32_t rd_count,
249 else 254 else
250 packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR; 255 packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR;
251 packet->flags.query_or_response = 1; 256 packet->flags.query_or_response = 1;
252 ret = GNUNET_DNSPARSER_pack (packet, 257 ret = GNUNET_DNSPARSER_pack(packet,
253 1024, /* maximum allowed size for DNS reply */ 258 1024, /* maximum allowed size for DNS reply */
254 &buf, 259 &buf,
255 &len); 260 &len);
256 if (GNUNET_OK != ret) 261 if (GNUNET_OK != ret)
257 { 262 {
258 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 263 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
259 _("Error converting GNS response to DNS response!\n")); 264 _("Error converting GNS response to DNS response!\n"));
260 if (GNUNET_NO == ret) 265 if (GNUNET_NO == ret)
261 GNUNET_free (buf); 266 GNUNET_free(buf);
262 } 267 }
263 else 268 else
264 { 269 {
265 GNUNET_DNS_request_answer (ilh->request_handle, 270 GNUNET_DNS_request_answer(ilh->request_handle,
266 len, 271 len,
267 buf); 272 buf);
268 GNUNET_free (buf); 273 GNUNET_free(buf);
269 } 274 }
270 packet->num_answers = 0; 275 packet->num_answers = 0;
271 packet->answers = NULL; 276 packet->answers = NULL;
272 packet->num_additional_records = 0; 277 packet->num_additional_records = 0;
273 packet->additional_records = NULL; 278 packet->additional_records = NULL;
274 GNUNET_DNSPARSER_free_packet (packet); 279 GNUNET_DNSPARSER_free_packet(packet);
275 } 280 }
276 GNUNET_CONTAINER_DLL_remove (ilh_head, ilh_tail, ilh); 281 GNUNET_CONTAINER_DLL_remove(ilh_head, ilh_tail, ilh);
277 GNUNET_free (ilh); 282 GNUNET_free(ilh);
278} 283}
279 284
280 285
@@ -287,61 +292,61 @@ reply_to_dns (void *cls, uint32_t rd_count,
287 * @param request UDP payload of the DNS request 292 * @param request UDP payload of the DNS request
288 */ 293 */
289static void 294static void
290handle_dns_request (void *cls, 295handle_dns_request(void *cls,
291 struct GNUNET_DNS_RequestHandle *rh, 296 struct GNUNET_DNS_RequestHandle *rh,
292 size_t request_length, 297 size_t request_length,
293 const char *request) 298 const char *request)
294{ 299{
295 struct GNUNET_DNSPARSER_Packet *p; 300 struct GNUNET_DNSPARSER_Packet *p;
296 struct InterceptLookupHandle *ilh; 301 struct InterceptLookupHandle *ilh;
297 struct GNUNET_CRYPTO_EcdsaPublicKey zone; 302 struct GNUNET_CRYPTO_EcdsaPublicKey zone;
298 303
299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 304 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
300 "Hijacked a DNS request. Processing.\n"); 305 "Hijacked a DNS request. Processing.\n");
301 if (NULL == (p = GNUNET_DNSPARSER_parse (request, request_length))) 306 if (NULL == (p = GNUNET_DNSPARSER_parse(request, request_length)))
302 { 307 {
303 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 308 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
304 "Received malformed DNS packet, leaving it untouched.\n"); 309 "Received malformed DNS packet, leaving it untouched.\n");
305 GNUNET_DNS_request_forward (rh); 310 GNUNET_DNS_request_forward(rh);
306 GNUNET_DNSPARSER_free_packet (p); 311 GNUNET_DNSPARSER_free_packet(p);
307 return; 312 return;
308 } 313 }
309 314
310 /* Check TLD and decide if we or legacy dns is responsible */ 315 /* Check TLD and decide if we or legacy dns is responsible */
311 if (1 != p->num_queries) 316 if (1 != p->num_queries)
312 { 317 {
313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 318 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
314 "Not exactly one query in DNS packet. Forwarding untouched.\n"); 319 "Not exactly one query in DNS packet. Forwarding untouched.\n");
315 GNUNET_DNS_request_forward (rh); 320 GNUNET_DNS_request_forward(rh);
316 GNUNET_DNSPARSER_free_packet(p); 321 GNUNET_DNSPARSER_free_packet(p);
317 return; 322 return;
318 } 323 }
319 324
320 /* Check for GNS TLDs. */ 325 /* Check for GNS TLDs. */
321 if (GNUNET_YES == 326 if (GNUNET_YES ==
322 GNS_find_tld (GNS_get_tld (p->queries[0].name), 327 GNS_find_tld(GNS_get_tld(p->queries[0].name),
323 &zone)) 328 &zone))
324 { 329 {
325 /* Start resolution in GNS */ 330 /* Start resolution in GNS */
326 ilh = GNUNET_new (struct InterceptLookupHandle); 331 ilh = GNUNET_new(struct InterceptLookupHandle);
327 GNUNET_CONTAINER_DLL_insert (ilh_head, 332 GNUNET_CONTAINER_DLL_insert(ilh_head,
328 ilh_tail, 333 ilh_tail,
329 ilh); 334 ilh);
330 ilh->packet = p; 335 ilh->packet = p;
331 ilh->request_handle = rh; 336 ilh->request_handle = rh;
332 ilh->lookup = GNS_resolver_lookup (&zone, 337 ilh->lookup = GNS_resolver_lookup(&zone,
333 p->queries[0].type, 338 p->queries[0].type,
334 p->queries[0].name, 339 p->queries[0].name,
335 GNUNET_NO, 340 GNUNET_NO,
336 &reply_to_dns, ilh); 341 &reply_to_dns, ilh);
337 return; 342 return;
338 } 343 }
339 /* This request does not concern us. Forward to real DNS. */ 344 /* This request does not concern us. Forward to real DNS. */
340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 345 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
341 "Request for `%s' is forwarded to DNS untouched.\n", 346 "Request for `%s' is forwarded to DNS untouched.\n",
342 p->queries[0].name); 347 p->queries[0].name);
343 GNUNET_DNS_request_forward (rh); 348 GNUNET_DNS_request_forward(rh);
344 GNUNET_DNSPARSER_free_packet (p); 349 GNUNET_DNSPARSER_free_packet(p);
345} 350}
346 351
347 352
@@ -352,20 +357,20 @@ handle_dns_request (void *cls,
352 * @return #GNUNET_OK on success 357 * @return #GNUNET_OK on success
353 */ 358 */
354int 359int
355GNS_interceptor_init (const struct GNUNET_CONFIGURATION_Handle *c) 360GNS_interceptor_init(const struct GNUNET_CONFIGURATION_Handle *c)
356{ 361{
357 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 362 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
358 "DNS hijacking enabled. Connecting to DNS service.\n"); 363 "DNS hijacking enabled. Connecting to DNS service.\n");
359 dns_handle = GNUNET_DNS_connect (c, 364 dns_handle = GNUNET_DNS_connect(c,
360 GNUNET_DNS_FLAG_PRE_RESOLUTION, 365 GNUNET_DNS_FLAG_PRE_RESOLUTION,
361 &handle_dns_request, 366 &handle_dns_request,
362 NULL); 367 NULL);
363 if (NULL == dns_handle) 368 if (NULL == dns_handle)
364 { 369 {
365 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 370 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
366 _("Failed to connect to the DNS service!\n")); 371 _("Failed to connect to the DNS service!\n"));
367 return GNUNET_SYSERR; 372 return GNUNET_SYSERR;
368 } 373 }
369 return GNUNET_YES; 374 return GNUNET_YES;
370} 375}
371 376
@@ -374,25 +379,25 @@ GNS_interceptor_init (const struct GNUNET_CONFIGURATION_Handle *c)
374 * Disconnect from interceptor 379 * Disconnect from interceptor
375 */ 380 */
376void 381void
377GNS_interceptor_done () 382GNS_interceptor_done()
378{ 383{
379 struct InterceptLookupHandle *ilh; 384 struct InterceptLookupHandle *ilh;
380 385
381 while (NULL != (ilh = ilh_head)) 386 while (NULL != (ilh = ilh_head))
382 { 387 {
383 GNUNET_CONTAINER_DLL_remove (ilh_head, 388 GNUNET_CONTAINER_DLL_remove(ilh_head,
384 ilh_tail, 389 ilh_tail,
385 ilh); 390 ilh);
386 GNS_resolver_lookup_cancel (ilh->lookup); 391 GNS_resolver_lookup_cancel(ilh->lookup);
387 GNUNET_DNS_request_drop (ilh->request_handle); 392 GNUNET_DNS_request_drop(ilh->request_handle);
388 GNUNET_DNSPARSER_free_packet (ilh->packet); 393 GNUNET_DNSPARSER_free_packet(ilh->packet);
389 GNUNET_free (ilh); 394 GNUNET_free(ilh);
390 } 395 }
391 if (NULL != dns_handle) 396 if (NULL != dns_handle)
392 { 397 {
393 GNUNET_DNS_disconnect (dns_handle); 398 GNUNET_DNS_disconnect(dns_handle);
394 dns_handle = NULL; 399 dns_handle = NULL;
395 } 400 }
396} 401}
397 402
398/* end of gnunet-service-gns_interceptor.c */ 403/* end of gnunet-service-gns_interceptor.c */