#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_dnsparser_lib.h"
+#include "dnsparser.h"
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/* FIXME: replace this one with the one from tcpip_tun.h!? */
-/**
- * Head of a any DNS message.
- */
-struct GNUNET_TUN_DnsHeader
-{
- /**
- * Request/response ID. (NBO)
- */
- uint16_t id GNUNET_PACKED;
-
- /**
- * Flags for the operation.
- */
- struct GNUNET_DNSPARSER_Flags flags;
-
- /**
- * number of questions (NBO)
- */
- uint16_t query_count GNUNET_PACKED;
-
- /**
- * number of answers (NBO)
- */
- uint16_t answer_rcount GNUNET_PACKED;
-
- /**
- * number of authority-records (NBO)
- */
- uint16_t authority_rcount GNUNET_PACKED;
-
- /**
- * number of additional records (NBO)
- */
- uint16_t additional_rcount GNUNET_PACKED;
-};
-
-
-/**
- * DNS query prefix.
- */
-struct query_line
-{
- /**
- * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
- */
- uint16_t type GNUNET_PACKED;
-
- /**
- * Desired class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO)
- */
- uint16_t class GNUNET_PACKED;
-};
-
-
-/**
- * General DNS record prefix.
- */
-struct record_line
-{
- /**
- * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
- */
- uint16_t type GNUNET_PACKED;
-
- /**
- * Record class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO)
- */
- uint16_t class GNUNET_PACKED;
-
- /**
- * Expiration for the record (in seconds). (NBO)
- */
- uint32_t ttl GNUNET_PACKED;
-
- /**
- * Number of bytes of data that follow. (NBO)
- */
- uint16_t data_len GNUNET_PACKED;
-};
-
-
-/**
- * Payload of DNS SOA record (header).
- */
-struct soa_data
-{
- /**
- * The version number of the original copy of the zone. (NBO)
- */
- uint32_t serial GNUNET_PACKED;
-
- /**
- * Time interval before the zone should be refreshed. (NBO)
- */
- uint32_t refresh GNUNET_PACKED;
-
- /**
- * Time interval that should elapse before a failed refresh should
- * be retried. (NBO)
- */
- uint32_t retry GNUNET_PACKED;
-
- /**
- * Time value that specifies the upper limit on the time interval
- * that can elapse before the zone is no longer authoritative. (NBO)
- */
- uint32_t expire GNUNET_PACKED;
-
- /**
- * The bit minimum TTL field that should be exported with any RR
- * from this zone. (NBO)
- */
- uint32_t minimum GNUNET_PACKED;
-};
-
-
-/**
- * Payload of DNS SRV record (header).
- */
-struct srv_data
-{
-
- /**
- * Preference for this entry (lower value is higher preference). Clients
- * will contact hosts from the lowest-priority group first and fall back
- * to higher priorities if the low-priority entries are unavailable. (NBO)
- */
- uint16_t prio GNUNET_PACKED;
-
- /**
- * Relative weight for records with the same priority. Clients will use
- * the hosts of the same (lowest) priority with a probability proportional
- * to the weight given. (NBO)
- */
- uint16_t weight GNUNET_PACKED;
-
- /**
- * TCP or UDP port of the service. (NBO)
- */
- uint16_t port GNUNET_PACKED;
-
- /* followed by 'target' name */
-};
-
-GNUNET_NETWORK_STRUCT_END
-
/**
* Parse name inside of a DNS query or record.
--- /dev/null
+/*
+ This file is part of GNUnet
+ (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file dns/dnsparser.h
+ * @brief helper library to parse DNS packets.
+ * @author Philipp Toelke
+ * @author Christian Grothoff
+ * @author Martin Schanzenbach
+ */
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/* FIXME: replace this one with the one from tcpip_tun.h!? */
+/**
+ * Head of a any DNS message.
+ */
+struct GNUNET_TUN_DnsHeader
+{
+ /**
+ * Request/response ID. (NBO)
+ */
+ uint16_t id GNUNET_PACKED;
+
+ /**
+ * Flags for the operation.
+ */
+ struct GNUNET_DNSPARSER_Flags flags;
+
+ /**
+ * number of questions (NBO)
+ */
+ uint16_t query_count GNUNET_PACKED;
+
+ /**
+ * number of answers (NBO)
+ */
+ uint16_t answer_rcount GNUNET_PACKED;
+
+ /**
+ * number of authority-records (NBO)
+ */
+ uint16_t authority_rcount GNUNET_PACKED;
+
+ /**
+ * number of additional records (NBO)
+ */
+ uint16_t additional_rcount GNUNET_PACKED;
+};
+
+
+/**
+ * DNS query prefix.
+ */
+struct query_line
+{
+ /**
+ * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
+ */
+ uint16_t type GNUNET_PACKED;
+
+ /**
+ * Desired class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO)
+ */
+ uint16_t class GNUNET_PACKED;
+};
+
+
+/**
+ * General DNS record prefix.
+ */
+struct record_line
+{
+ /**
+ * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO)
+ */
+ uint16_t type GNUNET_PACKED;
+
+ /**
+ * Record class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO)
+ */
+ uint16_t class GNUNET_PACKED;
+
+ /**
+ * Expiration for the record (in seconds). (NBO)
+ */
+ uint32_t ttl GNUNET_PACKED;
+
+ /**
+ * Number of bytes of data that follow. (NBO)
+ */
+ uint16_t data_len GNUNET_PACKED;
+};
+
+
+/**
+ * Payload of DNS SOA record (header).
+ */
+struct soa_data
+{
+ /**
+ * The version number of the original copy of the zone. (NBO)
+ */
+ uint32_t serial GNUNET_PACKED;
+
+ /**
+ * Time interval before the zone should be refreshed. (NBO)
+ */
+ uint32_t refresh GNUNET_PACKED;
+
+ /**
+ * Time interval that should elapse before a failed refresh should
+ * be retried. (NBO)
+ */
+ uint32_t retry GNUNET_PACKED;
+
+ /**
+ * Time value that specifies the upper limit on the time interval
+ * that can elapse before the zone is no longer authoritative. (NBO)
+ */
+ uint32_t expire GNUNET_PACKED;
+
+ /**
+ * The bit minimum TTL field that should be exported with any RR
+ * from this zone. (NBO)
+ */
+ uint32_t minimum GNUNET_PACKED;
+};
+
+
+/**
+ * Payload of DNS SRV record (header).
+ */
+struct srv_data
+{
+
+ /**
+ * Preference for this entry (lower value is higher preference). Clients
+ * will contact hosts from the lowest-priority group first and fall back
+ * to higher priorities if the low-priority entries are unavailable. (NBO)
+ */
+ uint16_t prio GNUNET_PACKED;
+
+ /**
+ * Relative weight for records with the same priority. Clients will use
+ * the hosts of the same (lowest) priority with a probability proportional
+ * to the weight given. (NBO)
+ */
+ uint16_t weight GNUNET_PACKED;
+
+ /**
+ * TCP or UDP port of the service. (NBO)
+ */
+ uint16_t port GNUNET_PACKED;
+
+ /* followed by 'target' name */
+};
+
+/**
+ * Payload of GNS VPN record
+ */
+struct vpn_data
+{
+ /**
+ * The protocol to use
+ */
+ uint16_t proto;
+
+ /**
+ * The peer to contact
+ */
+ struct GNUNET_HashCode peer;
+
+ /* followed by the servicename */
+};
+
+GNUNET_NETWORK_STRUCT_END
#include "gnunet_dns_service.h"
#include "gnunet_resolver_service.h"
#include "gnunet_dnsparser_lib.h"
+#include "../dns/dnsparser.h"
#include "gnunet_gns_service.h"
#include "block_gns.h"
#include "gns.h"
int rd_count,
const struct GNUNET_NAMESTORE_RecordData *rd)
{
- int af;
- int proto;
- struct GNUNET_HashCode peer_id;
- struct GNUNET_CRYPTO_HashAsciiEncoded s_pid;
+ struct RecordLookupHandle *rlh = rh->proc_cls;
struct GNUNET_HashCode serv_desc;
- struct GNUNET_CRYPTO_HashAsciiEncoded s_sd;
- char* pos;
- size_t len = (sizeof (uint32_t) * 2) + (sizeof (struct GNUNET_HashCode) * 2);
+ struct vpn_data* vpn;
+ int af;
/* We cancel here as to not include the ns lookup in the timeout */
if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK)
rh->priv_key);
}
- /* Extracting VPN information FIXME rd parsing with NS API?*/
- if (len != rd->data_size)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "GNS_PHASE_REC_VPN-%llu: Error parsing VPN RR!\n",
- rh->id);
- finish_lookup (rh, rh->proc_cls, 0, NULL);
- free_resolver_handle (rh);
- return;
- }
+ vpn = (struct vpn_data*)rd;
- pos = (char*)rd;
- memcpy (&af, pos, sizeof (uint32_t));
- pos += sizeof (uint32_t);
- memcpy (&proto, pos, sizeof (uint32_t));
- pos += sizeof (uint32_t);
- memcpy (&s_pid, pos, sizeof (struct GNUNET_HashCode));
- pos += sizeof (struct GNUNET_HashCode);
- memcpy (&s_sd, pos, sizeof (struct GNUNET_HashCode));
-
- if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_pid, &peer_id)) ||
- (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_sd, &serv_desc)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "GNS_PHASE_REC_VPN-%llu: Error parsing VPN RR hashes!\n",
- rh->id);
- finish_lookup (rh, rh->proc_cls, 0, NULL);
- free_resolver_handle (rh);
- return;
- }
+ GNUNET_CRYPTO_hash ((char*)&vpn[1],
+ strlen ((char*)&vpn[1]),
+ &serv_desc);
rh->proc = &handle_record_vpn;
free_resolver_handle (rh);
return;
}
+
+ if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_A)
+ af = AF_INET;
+ else
+ af = AF_INET6;
//FIXME timeout??
rh->vpn_handle = GNUNET_VPN_redirect_to_peer (vpn_handle,
- af, proto,
- (struct GNUNET_PeerIdentity*)&peer_id,
+ af, ntohs (vpn->proto),
+ (struct GNUNET_PeerIdentity *)&vpn->peer,
&serv_desc,
GNUNET_NO, //nac
GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME
static void
-expand_plus(char** dest, char* src, char* repl)
+expand_plus(char* dest, char* src, char* repl)
{
char* pos;
unsigned int s_len = strlen(src)+1;
"GNS_POSTPROCESS: %s to short\n", src);
/* no postprocessing */
- memcpy(*dest, src, s_len+1);
+ memcpy(dest, src, s_len+1);
return;
}
{
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"GNS_POSTPROCESS: Expanding .+ in %s\n", src);
- memset(*dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD));
- strcpy(*dest, src);
- pos = *dest+s_len-2;
+ memset(dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD));
+ strcpy(dest, src);
+ pos = dest+s_len-2;
strcpy(pos, repl);
pos += strlen(repl);
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
- "GNS_POSTPROCESS: Expanded to %s\n", *dest);
+ "GNS_POSTPROCESS: Expanded to %s\n", dest);
}
else
{
- memcpy(*dest, src, s_len+1);
+ memcpy(dest, src, s_len+1);
}
}
char new_mx_data[MAX_MX_LENGTH];
char new_soa_data[MAX_SOA_LENGTH];
char new_srv_data[MAX_SRV_LENGTH];
+ struct srv_data *old_srv;
+ struct srv_data *new_srv;
+ struct soa_data *old_soa;
+ struct soa_data *new_soa;
struct GNUNET_NAMESTORE_RecordData p_rd[rd_count];
char* repl_string;
char* pos;
memcpy (new_mx_data, (char*)rd[i].data, sizeof(uint16_t));
offset = sizeof(uint16_t);
pos = new_mx_data+offset;
- expand_plus(&pos, (char*)rd[i].data+sizeof(uint16_t),
+ expand_plus(pos, (char*)rd[i].data+sizeof(uint16_t),
repl_string);
offset += strlen(new_mx_data+sizeof(uint16_t))+1;
p_rd[i].data = new_mx_data;
/*
* Prio, weight and port
*/
- memcpy (new_srv_data, (char*)rd[i].data, sizeof (uint16_t) * 3);
- offset = sizeof (uint16_t) * 3;
- pos = new_srv_data+offset;
- expand_plus(&pos, (char*)rd[i].data+(sizeof(uint16_t)*3),
+ new_srv = (struct srv_data*)new_srv_data;
+ old_srv = (struct srv_data*)rd[i].data;
+ new_srv->prio = old_srv->prio;
+ new_srv->weight = old_srv->weight;
+ new_srv->port = old_srv->port;
+ expand_plus((char*)&new_srv[1], (char*)&old_srv[1],
repl_string);
- offset += strlen(new_srv_data+(sizeof(uint16_t)*3))+1;
p_rd[i].data = new_srv_data;
- p_rd[i].data_size = offset;
+ p_rd[i].data_size = sizeof (struct srv_data) + strlen ((char*)&new_srv[1]) + 1;
}
else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA)
{
/* expand mname and rname */
- pos = new_soa_data;
- expand_plus(&pos, (char*)rd[i].data, repl_string);
- offset = strlen(new_soa_data)+1;
- pos = new_soa_data+offset;
- expand_plus(&pos, (char*)rd[i].data+offset, repl_string);
- offset += strlen(new_soa_data+offset)+1;
- /* cpy the 4 numbers serial refresh retry and expire */
- memcpy(new_soa_data+offset, (char*)rd[i].data+offset, sizeof(uint32_t)*5);
- offset += sizeof(uint32_t)*5;
- p_rd[i].data_size = offset;
+ old_soa = (struct soa_data*)rd[i].data;
+ new_soa = (struct soa_data*)new_soa_data;
+ memcpy (new_soa, old_soa, sizeof (struct soa_data));
+ expand_plus((char*)&new_soa[1], (char*)&old_soa[1], repl_string);
+ offset = strlen ((char*)&new_soa[1]) + 1;
+ expand_plus((char*)&new_soa[1] + offset,
+ (char*)&old_soa[1] + strlen ((char*)&old_soa[1]) + 1,
+ repl_string);
+ p_rd[i].data_size = sizeof (struct soa_data)
+ + offset
+ + strlen ((char*)&new_soa[1] + offset);
p_rd[i].data = new_soa_data;
}
else
{
pos = new_rr_data;
- expand_plus(&pos, (char*)rd[i].data, repl_string);
+ expand_plus(pos, (char*)rd[i].data, repl_string);
p_rd[i].data_size = strlen(new_rr_data)+1;
p_rd[i].data = new_rr_data;
}
#include "gnunet_arm_service.h"
#include "gnunet_namestore_service.h"
#include "gnunet_dnsparser_lib.h"
+#include "../dns/dnsparser.h"
#include "namestore.h"
char* result;
char* soa_rname;
char* soa_mname;
- uint32_t* soa_data;
- uint32_t soa_serial;
- uint32_t soa_refresh;
- uint32_t soa_retry;
- uint32_t soa_expire;
- uint32_t soa_min;
- uint32_t *af;
- uint32_t *proto;
+ struct soa_data *soa;
+
+ struct vpn_data *vpn;
char* vpn_str;
- struct GNUNET_HashCode *h_peer;
- struct GNUNET_HashCode *h_serv;
+ char* srv_str;
struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
- struct GNUNET_CRYPTO_HashAsciiEncoded s_serv;
+ struct srv_data *srv;
switch (type)
{
case GNUNET_DNSPARSER_TYPE_CNAME:
return GNUNET_strndup (data, data_size);
case GNUNET_DNSPARSER_TYPE_SOA:
- soa_rname = (char*)data;
- soa_mname = (char*)data+strlen(soa_rname)+1;
- soa_data = (uint32_t*)(soa_mname+strlen(soa_mname)+1);
- soa_serial = ntohl(soa_data[0]);
- soa_refresh = ntohl(soa_data[1]);
- soa_retry = ntohl(soa_data[2]);
- soa_expire = ntohl(soa_data[3]);
- soa_min = ntohl(soa_data[4]);
+ soa = (struct soa_data*)data;
+ soa_rname = (char*)&soa[1];
+ soa_mname = (char*)&soa[1]+strlen(soa_rname)+1;
if (GNUNET_asprintf(&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
soa_rname, soa_mname,
- soa_serial, soa_refresh, soa_retry, soa_expire, soa_min))
+ ntohl (soa->serial), ntohl (soa->refresh),
+ ntohl (soa->retry), ntohl (soa->expire), ntohl (soa->minimum)))
return result;
else
return NULL;
case GNUNET_NAMESTORE_TYPE_LEHO:
return GNUNET_strndup (data, data_size);
case GNUNET_NAMESTORE_TYPE_VPN:
- af = (uint32_t*)data;
- proto = (uint32_t*)((char*)af + sizeof (uint32_t));
- h_peer = (struct GNUNET_HashCode*)((char*)proto + sizeof (struct GNUNET_HashCode));
- h_serv = (struct GNUNET_HashCode*)((char*)h_peer + sizeof (struct GNUNET_HashCode));
-
- GNUNET_CRYPTO_hash_to_enc (h_peer, &s_peer);
- GNUNET_CRYPTO_hash_to_enc (h_serv, &s_serv);
- if (GNUNET_OK != GNUNET_asprintf (&vpn_str, "%d:%d:%s:%s", af, proto, (char*)&s_peer, (char*)&s_serv))
+ vpn = (struct vpn_data*)data;
+
+ GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer);
+ if (GNUNET_OK != GNUNET_asprintf (&vpn_str, "%d:%s:%s",
+ vpn->proto,
+ (char*)&s_peer,
+ (char*)&vpn[1]))
return NULL;
return vpn_str;
+ case GNUNET_DNSPARSER_TYPE_SRV:
+ srv = (struct srv_data*)data;
+
+ if (GNUNET_OK != GNUNET_asprintf (&srv_str, "%d:%d:%d:%s",
+ ntohs (srv->prio),
+ ntohs (srv->weight),
+ ntohs (srv->port),
+ (char*)&srv[1]))
+ return NULL;
+ return srv_str;
default:
GNUNET_break (0);
}
struct GNUNET_CRYPTO_ShortHashCode pkey;
uint16_t mx_pref;
uint16_t mx_pref_n;
- uint32_t soa_data[5];
+ struct soa_data *soa;
char result[253];
char soa_rname[63];
char soa_mname[63];
uint32_t soa_retry;
uint32_t soa_expire;
uint32_t soa_min;
- struct GNUNET_HashCode *h_peer;
- struct GNUNET_HashCode *h_serv;
struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
- struct GNUNET_CRYPTO_HashAsciiEncoded s_serv;
- uint32_t* af;
- uint32_t* proto;
+ char s_serv[253];
+ struct vpn_data* vpn;
+ uint16_t proto;
switch (type)
{
!= 7)
return GNUNET_SYSERR;
- *data_size = sizeof (soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
+ *data_size = sizeof (struct soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
*data = GNUNET_malloc (*data_size);
- soa_data[0] = htonl(soa_serial);
- soa_data[1] = htonl(soa_refresh);
- soa_data[2] = htonl(soa_retry);
- soa_data[3] = htonl(soa_expire);
- soa_data[4] = htonl(soa_min);
- strcpy(*data, soa_rname);
- strcpy(*data+strlen(*data)+1, soa_mname);
- memcpy(*data+strlen(*data)+1+strlen(soa_mname)+1,
- soa_data, sizeof(soa_data));
+ soa = (struct soa_data*)*data;
+ soa->serial = htonl(soa_serial);
+ soa->refresh = htonl(soa_refresh);
+ soa->retry = htonl(soa_retry);
+ soa->expire = htonl(soa_expire);
+ soa->minimum = htonl(soa_min);
+ strcpy((char*)&soa[1], soa_rname);
+ strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname);
return GNUNET_OK;
case GNUNET_DNSPARSER_TYPE_PTR:
return GNUNET_OK;
case GNUNET_NAMESTORE_TYPE_VPN:
- *data_size = sizeof (uint32_t) * 2;
- *data_size += sizeof (struct GNUNET_HashCode) * 2;
- *data = GNUNET_malloc (*data_size);
- af = (uint32_t*)(*data);
- proto = (uint32_t*) ((char*)af + sizeof (uint32_t));
- h_peer = (struct GNUNET_HashCode*)((char*)proto + sizeof (uint32_t));
- h_serv = (struct GNUNET_HashCode*)((char*)h_peer + sizeof (struct GNUNET_HashCode));
- if (4 != SSCANF (s,"%d:%d:%s:%s",
- af, proto, (char*)&s_peer, (char*)&s_serv))
+ if (4 != SSCANF (s,"%hu:%s:%s",
+ &proto, (char*)&s_peer, s_serv))
{
return GNUNET_SYSERR;
}
- if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, h_peer)) ||
- (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_serv, h_serv)))
+ *data_size = sizeof (struct vpn_data) + strlen (s_serv) + 1;
+
+ *data = GNUNET_malloc (*data_size);
+
+ vpn = (struct vpn_data*)*data;
+
+ if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, &vpn->peer))
{
GNUNET_free (*data);
return GNUNET_SYSERR;
}
+
+ vpn->proto = htons (proto);
+ strcpy ((char*)&vpn[1], s_serv);
return GNUNET_OK;
default:
GNUNET_break (0);