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