#include "gnunet_signatures.h"
#include "dns.h"
#include "gnunet_dns_service.h"
+#include "gnunet_dnsparser_lib.h"
#include "gnunet_mesh_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_tun_lib.h"
};
+/**
+ * Global return value from 'main'.
+ */
+static int global_ret;
+
/**
* The configuration to use
*/
/**
* We're done with a RequestSocket, close it for now.
*
- * @param rr request to clean up
+ * @param rs request socket to clean up
*/
static void
cleanup_rs (struct RequestSocket *rs)
GNUNET_free (dns_exit);
dns_exit = NULL;
}
+ if (NULL != mesh)
+ {
+ GNUNET_MESH_disconnect(mesh);
+ mesh = NULL;
+ }
}
break;
default:
GNUNET_break (0);
+ GNUNET_NETWORK_socket_close (ret);
return NULL;
}
sa->sa_family = af;
return;
}
{
- char buf[reply_len];
+ char buf[reply_len] GNUNET_ALIGN;
size_t off;
struct GNUNET_TUN_IPv4Header ip4;
struct GNUNET_TUN_IPv6Header ip6;
}
/* final checks & sending */
GNUNET_assert (off == reply_len);
- GNUNET_HELPER_send (hijacker,
- hdr,
- GNUNET_YES,
- NULL, NULL);
+ (void) GNUNET_HELPER_send (hijacker,
+ hdr,
+ GNUNET_YES,
+ NULL, NULL);
GNUNET_STATISTICS_update (stats,
gettext_noop ("# DNS requests answered via TUN interface"),
1, GNUNET_NO);
send_request_to_client (struct RequestRecord *rr,
struct GNUNET_SERVER_Client *client)
{
- char buf[sizeof (struct GNUNET_DNS_Request) + rr->payload_length];
+ char buf[sizeof (struct GNUNET_DNS_Request) + rr->payload_length] GNUNET_ALIGN;
struct GNUNET_DNS_Request *req;
if (sizeof (buf) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
if (NULL != rs->dnsout6)
GNUNET_NETWORK_fdset_set (rset, rs->dnsout6);
rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK,
REQUEST_TIMEOUT,
rset,
NULL,
* if we have a valid, matching, pending request.
*
* @param dnsout socket to read from
- * @param GNUNET_OK on success, GNUNET_NO on drop, GNUNET_SYSERR on IO-errors (closed socket)
+ * @return GNUNET_OK on success, GNUNET_NO on drop, GNUNET_SYSERR on IO-errors (closed socket)
*/
static int
do_dns_read (struct GNUNET_NETWORK_Handle *dnsout)
#endif
{
- unsigned char buf[len];
+ unsigned char buf[len] GNUNET_ALIGN;
addrlen = sizeof (addr);
memset (&addr, 0, sizeof (addr));
if (NULL != rs->dnsout6)
GNUNET_NETWORK_fdset_set (rset, rs->dnsout6);
rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
- GNUNET_SCHEDULER_NO_TASK,
GNUNET_TIME_absolute_get_remaining (rs->timeout),
rset,
NULL,
return;
}
GNUNET_free_non_null (rr->payload);
-#if DEBUG_DNS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Changing DNS reply according to client specifications\n"));
-#endif
+ "Changing DNS reply according to client specifications\n");
rr->payload = GNUNET_malloc (msize);
rr->payload_length = msize;
memcpy (rr->payload, &resp[1], msize);
rr->client_wait_list_length,
0);
}
+ /* if query changed to answer, move past DNS resolution phase... */
+ if ( (RP_QUERY == rr->phase) &&
+ (rr->payload_length > sizeof (struct GNUNET_TUN_DnsHeader)) &&
+ ((struct GNUNET_DNSPARSER_Flags*)&(((struct GNUNET_TUN_DnsHeader*) rr->payload)->flags))->query_or_response == 1)
+ {
+ rr->phase = RP_INTERNET_DNS;
+ GNUNET_array_grow (rr->client_wait_list,
+ rr->client_wait_list_length,
+ 0);
+ }
break;
}
next_phase (rr);
* @param client identification of the client
* @param message the actual message, a DNS request we should handle
*/
-static void
+static int
process_helper_messages (void *cls GNUNET_UNUSED, void *client,
const struct GNUNET_MessageHeader *message)
{
{
/* non-IP packet received on TUN!? */
GNUNET_break (0);
- return;
+ return GNUNET_OK;
}
msize -= sizeof (struct GNUNET_MessageHeader);
tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
{
case ETH_P_IPV4:
ip4 = (const struct GNUNET_TUN_IPv4Header *) &tun[1];
+ ip6 = NULL; /* make compiler happy */
if ( (msize < sizeof (struct GNUNET_TUN_IPv4Header)) ||
(ip4->version != 4) ||
(ip4->header_length != sizeof (struct GNUNET_TUN_IPv4Header) / 4) ||
/* non-IP/UDP packet received on TUN (or with options) */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Received malformed IPv4-UDP packet on TUN interface.\n"));
- return;
+ return GNUNET_OK;
}
udp = (const struct GNUNET_TUN_UdpHeader*) &ip4[1];
msize -= sizeof (struct GNUNET_TUN_IPv4Header);
break;
case ETH_P_IPV6:
+ ip4 = NULL; /* make compiler happy */
ip6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
if ( (msize < sizeof (struct GNUNET_TUN_IPv6Header)) ||
(ip6->version != 6) ||
/* non-IP/UDP packet received on TUN (or with extensions) */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Received malformed IPv6-UDP packet on TUN interface.\n"));
- return;
+ return GNUNET_OK;
}
udp = (const struct GNUNET_TUN_UdpHeader*) &ip6[1];
msize -= sizeof (struct GNUNET_TUN_IPv6Header);
_("Got non-IP packet with %u bytes and protocol %u from TUN\n"),
(unsigned int) msize,
ntohs (tun->proto));
- return;
+ return GNUNET_OK;
}
if (msize <= sizeof (struct GNUNET_TUN_UdpHeader) + sizeof (struct GNUNET_TUN_DnsHeader))
{
GNUNET_STATISTICS_update (stats,
gettext_noop ("# Non-DNS UDP packet received via TUN interface"),
1, GNUNET_NO);
- return;
+ return GNUNET_OK;
}
msize -= sizeof (struct GNUNET_TUN_UdpHeader);
dns = (const struct GNUNET_TUN_DnsHeader*) &udp[1];
srca4->sin_port = udp->source_port;
dsta4->sin_port = udp->destination_port;
#if HAVE_SOCKADDR_IN_SIN_LEN
- srca4->sin_len = sizeof (struct sockaddr_in))
+ srca4->sin_len = sizeof (struct sockaddr_in);
dsta4->sin_len = sizeof (struct sockaddr_in);
#endif
}
1, GNUNET_NO);
/* start request processing state machine */
next_phase (rr);
+ return GNUNET_OK;
}
const struct GNUNET_TUN_DnsHeader *dns;
size_t mlen = ntohs (message->size);
size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader);
- char buf[dlen];
+ char buf[dlen] GNUNET_ALIGN;
struct GNUNET_TUN_DnsHeader *dout;
struct sockaddr_in v4;
struct sockaddr_in6 v6;
struct sockaddr *so;
socklen_t salen;
-
+
if (dlen < sizeof (struct GNUNET_TUN_DnsHeader))
{
GNUNET_break_op (0);
memcpy (buf, dns, dlen);
dout = (struct GNUNET_TUN_DnsHeader*) buf;
dout->id = ts->my_id;
-
memset (&v4, 0, sizeof (v4));
memset (&v6, 0, sizeof (v6));
if (1 == inet_pton (AF_INET, dns_exit, &v4.sin_addr))
#endif
so = (struct sockaddr *) &v4;
ts->dnsout = get_request_socket (AF_INET);
- }
- if (1 == inet_pton (AF_INET6, dns_exit, &v6.sin6_addr))
+ }
+ else if (1 == inet_pton (AF_INET6, dns_exit, &v6.sin6_addr))
{
salen = sizeof (v6);
v6.sin6_family = AF_INET6;
so = (struct sockaddr *) &v6;
ts->dnsout = get_request_socket (AF_INET6);
}
+ else
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
if (NULL == ts->dnsout)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
struct in6_addr dns_exit6;
cfg = cfg_;
+ if (GNUNET_YES !=
+ GNUNET_OS_check_helper_binary ("gnunet-helper-dns"))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("`%s' must be installed SUID, refusing to run\n"),
+ "gnunet-helper-dns");
+ global_ret = 1;
+ return;
+ }
+
stats = GNUNET_STATISTICS_create ("dns", cfg);
nc = GNUNET_SERVER_notification_context_create (server, 1);
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
&dns_exit)) ||
( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) &&
(1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) )
+ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Configured to provide DNS exit, but no valid DNS server configured!\n"));
+ GNUNET_free_non_null (dns_exit);
+ dns_exit = NULL;
+ }
helper_argv[0] = GNUNET_strdup ("gnunet-dns");
if (GNUNET_SYSERR ==
{
return (GNUNET_OK ==
GNUNET_SERVICE_run (argc, argv, "dns", GNUNET_SERVICE_OPTION_NONE,
- &run, NULL)) ? 0 : 1;
+ &run, NULL)) ? global_ret : 1;
}