* @file gns/gnunet-service-gns_interceptor.c
* @brief GNUnet GNS interceptor logic
* @author Martin Schanzenbach
+ * @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet_util_lib.h"
struct InterceptLookupHandle *prev;
/**
- * the request handle to reply to
+ * the request handle to reply to
*/
struct GNUNET_DNS_RequestHandle *request_handle;
-
+
/**
- * the dns parser packet received
+ * the dns parser packet received
*/
struct GNUNET_DNSPARSER_Packet *packet;
/**
* Key of the zone we start lookups in.
*/
-static struct GNUNET_CRYPTO_EccPublicKey zone;
+static struct GNUNET_CRYPTO_EcdsaPublicKey zone;
/**
* Head of the DLL.
int ret;
char *buf;
unsigned int num_answers;
-
+ unsigned int skip_answers;
+ unsigned int skip_additional;
+ size_t off;
+
/* Put records in the DNS packet */
num_answers = 0;
for (i=0; i < rd_count; i++)
if (rd[i].record_type == query->type)
num_answers++;
+ skip_answers = 0;
+ skip_additional = 0;
{
struct GNUNET_DNSPARSER_Record answer_records[num_answers];
packet->answers = answer_records;
packet->additional_records = additional_records;
-
+ /* FIXME: need to handle #GNUNET_NAMESTORE_RF_SHADOW_RECORD option
+ (by ignoring records where this flag is set if there is any
+ other record of that type in the result set) */
for (i=0; i < rd_count; i++)
{
if (rd[i].record_type == query->type)
{
- answer_records[i].name = query->name;
- answer_records[i].type = rd[i].record_type;
+ answer_records[i - skip_answers].name = query->name;
+ answer_records[i - skip_answers].type = rd[i].record_type;
switch(rd[i].record_type)
{
case GNUNET_DNSPARSER_TYPE_NS:
case GNUNET_DNSPARSER_TYPE_CNAME:
case GNUNET_DNSPARSER_TYPE_PTR:
- answer_records[i].data.hostname = (char*)rd[i].data;
+ answer_records[i - skip_answers].data.hostname
+ = GNUNET_DNSPARSER_parse_name (rd[i].data,
+ rd[i].data_size,
+ &off);
+ if ( (off != rd[i].data_size) ||
+ (NULL == answer_records[i].data.hostname) )
+ {
+ GNUNET_break_op (0);
+ skip_answers++;
+ }
break;
case GNUNET_DNSPARSER_TYPE_SOA:
- answer_records[i].data.soa =
- (struct GNUNET_DNSPARSER_SoaRecord *)rd[i].data;
+ answer_records[i - skip_answers].data.soa
+ = GNUNET_DNSPARSER_parse_soa (rd[i].data,
+ rd[i].data_size,
+ &off);
+ if ( (off != rd[i].data_size) ||
+ (NULL == answer_records[i].data.soa) )
+ {
+ GNUNET_break_op (0);
+ skip_answers++;
+ }
+ break;
+ case GNUNET_DNSPARSER_TYPE_SRV:
+ /* FIXME: SRV is not yet supported */
+ skip_answers++;
break;
case GNUNET_DNSPARSER_TYPE_MX:
- answer_records[i].data.mx =
- (struct GNUNET_DNSPARSER_MxRecord *)rd[i].data;
+ answer_records[i - skip_answers].data.mx
+ = GNUNET_DNSPARSER_parse_mx (rd[i].data,
+ rd[i].data_size,
+ &off);
+ if ( (off != rd[i].data_size) ||
+ (NULL == answer_records[i].data.hostname) )
+ {
+ GNUNET_break_op (0);
+ skip_answers++;
+ }
break;
default:
- answer_records[i].data.raw.data_len = rd[i].data_size;
- answer_records[i].data.raw.data = (char*)rd[i].data;
+ answer_records[i - skip_answers].data.raw.data_len = rd[i].data_size;
+ answer_records[i - skip_answers].data.raw.data = (char*)rd[i].data;
break;
}
- GNUNET_break (0 == (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION));
- answer_records[i].expiration_time.abs_value_us = rd[i].expiration_time;
- answer_records[i].class = GNUNET_TUN_DNS_CLASS_INTERNET;
+ GNUNET_break (0 == (rd[i - skip_answers].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION));
+ answer_records[i - skip_answers].expiration_time.abs_value_us = rd[i].expiration_time;
+ answer_records[i - skip_answers].dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
}
else
{
- additional_records[i].name = query->name;
- additional_records[i].type = rd[i].record_type;
+ additional_records[i - skip_additional].name = query->name;
+ additional_records[i - skip_additional].type = rd[i].record_type;
switch(rd[i].record_type)
{
case GNUNET_DNSPARSER_TYPE_NS:
case GNUNET_DNSPARSER_TYPE_CNAME:
case GNUNET_DNSPARSER_TYPE_PTR:
- additional_records[i].data.hostname = (char*)rd[i].data;
+ additional_records[i - skip_additional].data.hostname
+ = GNUNET_DNSPARSER_parse_name (rd[i].data,
+ rd[i].data_size,
+ &off);
+ if ( (off != rd[i].data_size) ||
+ (NULL == additional_records[i].data.hostname) )
+ {
+ GNUNET_break_op (0);
+ skip_additional++;
+ }
break;
case GNUNET_DNSPARSER_TYPE_SOA:
- additional_records[i].data.soa =
- (struct GNUNET_DNSPARSER_SoaRecord *)rd[i].data;
+ additional_records[i - skip_additional].data.soa
+ = GNUNET_DNSPARSER_parse_soa (rd[i].data,
+ rd[i].data_size,
+ &off);
+ if ( (off != rd[i].data_size) ||
+ (NULL == additional_records[i].data.hostname) )
+ {
+ GNUNET_break_op (0);
+ skip_additional++;
+ }
break;
case GNUNET_DNSPARSER_TYPE_MX:
- additional_records[i].data.mx =
- (struct GNUNET_DNSPARSER_MxRecord *)rd[i].data;
+ additional_records[i - skip_additional].data.mx
+ = GNUNET_DNSPARSER_parse_mx (rd[i].data,
+ rd[i].data_size,
+ &off);
+ if ( (off != rd[i].data_size) ||
+ (NULL == additional_records[i].data.hostname) )
+ {
+ GNUNET_break_op (0);
+ skip_additional++;
+ }
+ break;
+ case GNUNET_DNSPARSER_TYPE_SRV:
+ /* FIXME: SRV is not yet supported */
+ skip_answers++;
break;
default:
- additional_records[i].data.raw.data_len = rd[i].data_size;
- additional_records[i].data.raw.data = (char*)rd[i].data;
+ additional_records[i - skip_additional].data.raw.data_len = rd[i].data_size;
+ additional_records[i - skip_additional].data.raw.data = (char*)rd[i].data;
break;
}
- GNUNET_break (0 == (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION));
- additional_records[i].expiration_time.abs_value_us = rd[i].expiration_time;
- additional_records[i].class = GNUNET_TUN_DNS_CLASS_INTERNET;
+ GNUNET_break (0 == (rd[i - skip_additional].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION));
+ additional_records[i - skip_additional].expiration_time.abs_value_us = rd[i].expiration_time;
+ additional_records[i - skip_additional].dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
}
}
- packet->num_answers = num_answers;
- packet->num_additional_records = rd_count - num_answers;
+ packet->num_answers = num_answers - skip_answers;
+ packet->num_additional_records = rd_count - num_answers - skip_additional;
packet->flags.authoritative_answer = 1;
if (NULL == rd)
packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NAME_ERROR;
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Error converting GNS response to DNS response!\n"));
- }
+ }
else
{
GNUNET_DNS_request_answer (ilh->request_handle,
len,
buf);
GNUNET_free (buf);
- }
+ }
packet->num_answers = 0;
packet->answers = NULL;
packet->num_additional_records = 0;
struct GNUNET_DNSPARSER_Packet *p;
struct InterceptLookupHandle *ilh;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Hijacked a DNS request. Processing.\n");
if (NULL == (p = GNUNET_DNSPARSER_parse (request, request_length)))
{
GNUNET_DNSPARSER_free_packet (p);
return;
}
-
+
/* Check TLD and decide if we or legacy dns is responsible */
if (1 != p->num_queries)
{
return;
}
- /* Check for GNS TLDs. */
- if ( (GNUNET_YES == is_gads_tld (p->queries[0].name)) ||
+ /* Check for GNS TLDs. */
+ if ( (GNUNET_YES == is_gnu_tld (p->queries[0].name)) ||
(GNUNET_YES == is_zkey_tld (p->queries[0].name)) ||
(0 == strcmp (p->queries[0].name, GNUNET_GNS_TLD)) )
{
GNUNET_CONTAINER_DLL_insert (ilh_head, ilh_tail, ilh);
ilh->packet = p;
ilh->request_handle = rh;
- ilh->lookup = GNS_resolver_lookup (&zone,
- p->queries[0].type,
+ ilh->lookup = GNS_resolver_lookup (&zone,
+ p->queries[0].type,
p->queries[0].name,
NULL /* FIXME: enable shorten for DNS intercepts? */,
GNUNET_NO,
}
/* This request does not concern us. Forward to real DNS. */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Request for `%s' is forwarded to DNS untouched.\n",
+ "Request for `%s' is forwarded to DNS untouched.\n",
p->queries[0].name);
GNUNET_DNS_request_forward (rh);
GNUNET_DNSPARSER_free_packet (p);
*
* @param gnu_zone the zone to work in
* @param c the configuration
- * @return GNUNET_OK on success
+ * @return #GNUNET_OK on success
*/
int
-GNS_interceptor_init (const struct GNUNET_CRYPTO_EccPublicKey *gnu_zone,
+GNS_interceptor_init (const struct GNUNET_CRYPTO_EcdsaPublicKey *gnu_zone,
const struct GNUNET_CONFIGURATION_Handle *c)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,