[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r17761 - in gnunet: contrib src/vpn
From: |
gnunet |
Subject: |
[GNUnet-SVN] r17761 - in gnunet: contrib src/vpn |
Date: |
Wed, 26 Oct 2011 09:13:23 +0200 |
Author: toelke
Date: 2011-10-26 09:13:23 +0200 (Wed, 26 Oct 2011)
New Revision: 17761
Modified:
gnunet/contrib/defaults.conf
gnunet/src/vpn/gnunet-daemon-vpn-helper.c
gnunet/src/vpn/gnunet-service-dns-p.h
gnunet/src/vpn/gnunet-service-dns.c
gnunet/src/vpn/gnunet-vpn-packet.h
Log:
handle dns over ipv6 and 6-to-4 and 4-to-6
Modified: gnunet/contrib/defaults.conf
===================================================================
--- gnunet/contrib/defaults.conf 2011-10-26 00:02:43 UTC (rev 17760)
+++ gnunet/contrib/defaults.conf 2011-10-26 07:13:23 UTC (rev 17761)
@@ -470,6 +470,7 @@
IPV4ADDR = 10.11.10.1
IPV4MASK = 255.255.0.0
VIRTDNS = 10.11.10.2
+VIRTDNS6 = 1234::17
IFNAME = vpn-gnunet
[exit]
Modified: gnunet/src/vpn/gnunet-daemon-vpn-helper.c
===================================================================
--- gnunet/src/vpn/gnunet-daemon-vpn-helper.c 2011-10-26 00:02:43 UTC (rev
17760)
+++ gnunet/src/vpn/gnunet-daemon-vpn-helper.c 2011-10-26 07:13:23 UTC (rev
17761)
@@ -174,52 +174,114 @@
GNUNET_assert (20 == sizeof (struct ip_hdr));
GNUNET_assert (8 == sizeof (struct udp_pkt));
+
size_t data_len = len - sizeof (struct answer_packet) + 1;
- size_t net_len = sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len;
- size_t pkt_len =
- sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + net_len;
- struct ip_udp_dns *pkt = alloca (pkt_len);
+ void* buf;
+ size_t pkt_len;
- GNUNET_assert (pkt != NULL);
- memset (pkt, 0, pkt_len);
+ if (ans->pkt.addrlen == 16)
+ {
+ size_t net_len = sizeof (struct ip6_hdr) + sizeof (struct udp_dns) +
data_len;
+ pkt_len =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
net_len;
- /* set the gnunet-header */
- pkt->shdr.size = htons (pkt_len);
- pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
+ struct ip6_udp_dns *pkt = alloca (pkt_len);
- /* set the tun-header (no flags and ethertype of IPv4) */
- pkt->tun.flags = 0;
- pkt->tun.type = htons (0x0800);
+ GNUNET_assert (pkt != NULL);
+ memset (pkt, 0, pkt_len);
- /* set the ip-header */
- pkt->ip_hdr.version = 4;
- pkt->ip_hdr.hdr_lngth = 5;
- pkt->ip_hdr.diff_serv = 0;
- pkt->ip_hdr.tot_lngth = htons (net_len);
- pkt->ip_hdr.ident = 0;
- pkt->ip_hdr.flags = 0;
- pkt->ip_hdr.frag_off = 0;
- pkt->ip_hdr.ttl = 255;
- pkt->ip_hdr.proto = IPPROTO_UDP;
- pkt->ip_hdr.chks = 0; /* Will be calculated later */
- pkt->ip_hdr.sadr = ans->pkt.from;
- pkt->ip_hdr.dadr = ans->pkt.to;
+ /* set the gnunet-header */
+ pkt->shdr.size = htons (pkt_len);
+ pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
- pkt->ip_hdr.chks = calculate_ip_checksum ((uint16_t *) & pkt->ip_hdr, 5 * 4);
+ /* set the tun-header (no flags and ethertype of IPv4) */
+ pkt->tun.flags = 0;
+ pkt->tun.type = htons (0x86dd);
- /* set the udp-header */
- pkt->udp_dns.udp_hdr.spt = htons (53);
- pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
- pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
- pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
+ memcpy(&pkt->ip6_hdr.sadr, ans->pkt.from, 16);
+ memcpy(&pkt->ip6_hdr.dadr, ans->pkt.to, 16);
- memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
+ /* set the udp-header */
+ pkt->udp_dns.udp_hdr.spt = htons (53);
+ pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
+ pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr));
+ pkt->udp_dns.udp_hdr.crc = 0;
+ uint32_t sum = 0;
+ sum =
+ calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16);
+ sum =
+ calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16);
+ uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff);
+
+ sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
+ tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff)));
+ sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
+
+ sum =
+ calculate_checksum_update (sum, (uint16_t *) & pkt->udp_dns.udp_hdr,
+ ntohs (net_len - sizeof(struct ip6_hdr)));
+ pkt->udp_dns.udp_hdr.crc = calculate_checksum_end (sum);
+
+ pkt->ip6_hdr.version = 6;
+ pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr);
+ pkt->ip6_hdr.nxthdr = IPPROTO_UDP;
+ pkt->ip6_hdr.hoplmt = 0xff;
+
+ memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
+ buf = pkt;
+ }
+ else if (ans->pkt.addrlen == 4)
+ {
+ size_t net_len = sizeof (struct ip_hdr) + sizeof (struct udp_dns) +
data_len;
+ pkt_len =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
net_len;
+
+ struct ip_udp_dns *pkt = alloca (pkt_len);
+
+ GNUNET_assert (pkt != NULL);
+ memset (pkt, 0, pkt_len);
+
+ /* set the gnunet-header */
+ pkt->shdr.size = htons (pkt_len);
+ pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
+
+ /* set the tun-header (no flags and ethertype of IPv4) */
+ pkt->tun.flags = 0;
+ pkt->tun.type = htons (0x0800);
+
+ /* set the ip-header */
+ pkt->ip_hdr.version = 4;
+ pkt->ip_hdr.hdr_lngth = 5;
+ pkt->ip_hdr.diff_serv = 0;
+ pkt->ip_hdr.tot_lngth = htons (net_len);
+ pkt->ip_hdr.ident = 0;
+ pkt->ip_hdr.flags = 0;
+ pkt->ip_hdr.frag_off = 0;
+ pkt->ip_hdr.ttl = 255;
+ pkt->ip_hdr.proto = IPPROTO_UDP;
+ pkt->ip_hdr.chks = 0; /* Will be calculated later */
+
+ memcpy(&pkt->ip_hdr.sadr, ans->pkt.from, 4);
+ memcpy(&pkt->ip_hdr.dadr, ans->pkt.to, 4);
+
+ pkt->ip_hdr.chks = calculate_ip_checksum ((uint16_t *) & pkt->ip_hdr, 5
* 4);
+
+ /* set the udp-header */
+ pkt->udp_dns.udp_hdr.spt = htons (53);
+ pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
+ pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
+ pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
+
+ memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
+ buf = pkt;
+ }
+
GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans);
GNUNET_free (ans);
- if (GNUNET_DISK_file_write (helper_handle->fh_to_helper, pkt, pkt_len) < 0)
+ if (GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, pkt_len) < 0)
{
cleanup_helper (helper_handle);
GNUNET_SCHEDULER_add_now (start_helper_and_schedule, NULL);
@@ -258,11 +320,37 @@
switch (pkt6->ip6_hdr.nxthdr)
{
- case IPPROTO_TCP:
case IPPROTO_UDP:
- pkt6_tcp = (struct ip6_tcp *) pkt6;
pkt6_udp = (struct ip6_udp *) pkt6;
+ /* Send dns-packets to the service-dns */
+ if (ntohs (pkt6_udp->udp_hdr.dpt) == 53)
+ {
+ /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */
+ size_t len = sizeof (struct query_packet) + ntohs
(pkt6_udp->udp_hdr.len) - 9;
+ struct query_packet_list *query =
+ GNUNET_malloc (len + 2 * sizeof (struct query_packet_list *));
+ query->pkt.hdr.type = htons
(GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_QUERY_DNS);
+ query->pkt.hdr.size = htons (len);
+ memcpy(query->pkt.orig_to, &pkt6->ip6_hdr.dadr, 16);
+ memcpy(query->pkt.orig_from, &pkt6->ip6_hdr.sadr, 16);
+ query->pkt.addrlen = 16;
+ query->pkt.src_port = pkt6_udp->udp_hdr.spt;
+ memcpy (query->pkt.data, pkt6_udp->data, ntohs
(pkt6_udp->udp_hdr.len) - 8);
+
+ GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, query);
+
+ GNUNET_assert (head != NULL);
+
+ if (dns_connection != NULL && dns_transmit_handle == NULL)
+ dns_transmit_handle = GNUNET_CLIENT_notify_transmit_ready
(dns_connection, len,
+
GNUNET_TIME_UNIT_FOREVER_REL,
+
GNUNET_YES, &send_query, NULL);
+ break;
+ }
+ case IPPROTO_TCP:
+ pkt6_tcp = (struct ip6_tcp *) pkt6;
+
if ((key = address6_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
{
struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap,
key);
@@ -438,8 +526,9 @@
GNUNET_malloc (len + 2 * sizeof (struct query_packet_list *));
query->pkt.hdr.type = htons
(GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_QUERY_DNS);
query->pkt.hdr.size = htons (len);
- query->pkt.orig_to = pkt->ip_hdr.dadr;
- query->pkt.orig_from = pkt->ip_hdr.sadr;
+ memcpy(query->pkt.orig_to, &pkt->ip_hdr.dadr, 4);
+ memcpy(query->pkt.orig_from, &pkt->ip_hdr.sadr, 4);
+ query->pkt.addrlen = 4;
query->pkt.src_port = udp->udp_hdr.spt;
memcpy (query->pkt.data, udp->data, ntohs (udp->udp_hdr.len) - 8);
Modified: gnunet/src/vpn/gnunet-service-dns-p.h
===================================================================
--- gnunet/src/vpn/gnunet-service-dns-p.h 2011-10-26 00:02:43 UTC (rev
17760)
+++ gnunet/src/vpn/gnunet-service-dns-p.h 2011-10-26 07:13:23 UTC (rev
17761)
@@ -10,15 +10,16 @@
/**
* The IP-Address this query was originally sent to
*/
- unsigned orig_to:32 GNUNET_PACKED;
+ char orig_to[16];
/**
* The IP-Address this query was originally sent from
*/
- unsigned orig_from:32 GNUNET_PACKED;
+ char orig_from[16];
/**
* The UDP-Portthis query was originally sent from
*/
- unsigned src_port:16 GNUNET_PACKED;
+ char addrlen;
+ uint16_t src_port GNUNET_PACKED;
unsigned char data[1]; /* The DNS-Packet */
};
@@ -76,8 +77,9 @@
struct GNUNET_MessageHeader hdr;
enum GNUNET_DNS_ANSWER_Subtype subtype GNUNET_PACKED;
- unsigned from:32 GNUNET_PACKED;
- unsigned to:32 GNUNET_PACKED;
+ char from[16];
+ char to[16];
+ char addrlen;
unsigned dst_port:16 GNUNET_PACKED;
/* -- */
Modified: gnunet/src/vpn/gnunet-service-dns.c
===================================================================
--- gnunet/src/vpn/gnunet-service-dns.c 2011-10-26 00:02:43 UTC (rev 17760)
+++ gnunet/src/vpn/gnunet-service-dns.c 2011-10-26 07:13:23 UTC (rev 17761)
@@ -50,6 +50,7 @@
* sent through gnunet. The port of this socket will not be hijacked.
*/
static struct GNUNET_NETWORK_Handle *dnsout;
+static struct GNUNET_NETWORK_Handle *dnsout6;
/**
* The port bound to the socket dnsout
@@ -90,8 +91,9 @@
unsigned valid:1;
struct GNUNET_SERVER_Client *client;
struct GNUNET_MESH_Tunnel *tunnel;
- uint32_t local_ip;
- uint32_t remote_ip;
+ char local_ip[16];
+ char remote_ip[16];
+ char addrlen;
uint16_t local_port;
char *name;
uint8_t namelen;
@@ -485,9 +487,9 @@
memcpy (answer->pkt.addr, pdns->answers[0]->data,
ntohs (pdns->answers[0]->data_len));
- answer->pkt.from = query_states[dns->s.id].remote_ip;
-
- answer->pkt.to = query_states[dns->s.id].local_ip;
+ memcpy(answer->pkt.from, query_states[dns->s.id].remote_ip,
query_states[dns->s.id].addrlen);
+ memcpy(answer->pkt.to, query_states[dns->s.id].local_ip,
query_states[dns->s.id].addrlen);
+ answer->pkt.addrlen = query_states[dns->s.id].addrlen;
answer->pkt.dst_port = query_states[dns->s.id].local_port;
struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -589,9 +591,9 @@
answer->pkt.hdr.size = htons (len);
answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REV;
- answer->pkt.from = query_states[id].remote_ip;
+ memcpy(answer->pkt.from, query_states[id].remote_ip,
query_states[id].addrlen);
+ memcpy(answer->pkt.to, query_states[id].local_ip, query_states[id].addrlen);
- answer->pkt.to = query_states[id].local_ip;
answer->pkt.dst_port = query_states[id].local_port;
struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -700,9 +702,9 @@
memcpy (&answer->pkt.service_descr.ports, &rec->ports,
sizeof (answer->pkt.service_descr.ports));
- answer->pkt.from = query_states[id].remote_ip;
+ memcpy(answer->pkt.from, query_states[id].remote_ip,
query_states[id].addrlen);
+ memcpy(answer->pkt.to, query_states[id].local_ip, query_states[id].addrlen);
- answer->pkt.to = query_states[id].local_ip;
answer->pkt.dst_port = query_states[id].local_port;
struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -784,9 +786,10 @@
query_states[dns->s.id].valid = GNUNET_YES;
query_states[dns->s.id].client = client;
- query_states[dns->s.id].local_ip = pkt->orig_from;
+ memcpy(query_states[dns->s.id].local_ip, pkt->orig_from, pkt->addrlen);
+ query_states[dns->s.id].addrlen = pkt->addrlen;
query_states[dns->s.id].local_port = pkt->src_port;
- query_states[dns->s.id].remote_ip = pkt->orig_to;
+ memcpy(query_states[dns->s.id].remote_ip, pkt->orig_to, pkt->addrlen);
query_states[dns->s.id].namelen = strlen ((char *) dns->data) + 1;
if (query_states[dns->s.id].name != NULL)
GNUNET_free (query_states[dns->s.id].name);
@@ -883,27 +886,56 @@
}
}
- char *virt_dns;
- unsigned int virt_dns_bytes;
+ unsigned char virt_dns_bytes[16];
- if (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS", &virt_dns))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No entry 'VIRTDNS' in configuration!\n");
- exit (1);
- }
+ if (pkt->addrlen == 4)
+ {
+ char *virt_dns;
- if (1 != inet_pton (AF_INET, virt_dns, &virt_dns_bytes))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS': %s; %m!\n",
- virt_dns);
- exit (1);
- }
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS",
&virt_dns))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No entry 'VIRTDNS' in configuration!\n");
+ exit (1);
+ }
- GNUNET_free (virt_dns);
+ if (1 != inet_pton (AF_INET, virt_dns, &virt_dns_bytes))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS': %s;
%m!\n",
+ virt_dns);
+ exit (1);
+ }
- if (virt_dns_bytes == pkt->orig_to)
+ GNUNET_free (virt_dns);
+ }
+ else if (pkt->addrlen == 16)
+ {
+ char *virt_dns;
+
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS6",
&virt_dns))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No entry 'VIRTDNS6' in configuration!\n");
+ exit (1);
+ }
+
+ if (1 != inet_pton (AF_INET6, virt_dns, &virt_dns_bytes))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS6': %s;
%m!\n",
+ virt_dns);
+ exit (1);
+ }
+
+ GNUNET_free (virt_dns);
+ }
+ else
+ {
+ GNUNET_assert(0);
+ }
+
+ if (memcmp(virt_dns_bytes,pkt->orig_to, pkt->addrlen) == 0)
{
/* This is a packet that was sent directly to the virtual dns-server
*
@@ -958,18 +990,33 @@
/* The query should be sent to the network */
+ if (pkt->addrlen == 4)
+ {
+ struct sockaddr_in dest;
- struct sockaddr_in dest;
+ memset (&dest, 0, sizeof dest);
+ dest.sin_port = htons (53);
+ memcpy(&dest.sin_addr.s_addr, pkt->orig_to, pkt->addrlen);
- memset (&dest, 0, sizeof dest);
- dest.sin_port = htons (53);
- dest.sin_addr.s_addr = pkt->orig_to;
+ GNUNET_NETWORK_socket_sendto (dnsout, dns,
+ ntohs (pkt->hdr.size) -
+ sizeof (struct query_packet) + 1,
+ (struct sockaddr *) &dest, sizeof dest);
+ }
+ else if (pkt->addrlen == 16)
+ {
+ struct sockaddr_in6 dest;
- GNUNET_NETWORK_socket_sendto (dnsout, dns,
- ntohs (pkt->hdr.size) -
- sizeof (struct query_packet) + 1,
- (struct sockaddr *) &dest, sizeof dest);
+ memset (&dest, 0, sizeof dest);
+ dest.sin6_port = htons (53);
+ memcpy(&dest.sin6_addr, pkt->orig_to, pkt->addrlen);
+ GNUNET_NETWORK_socket_sendto (dnsout6, dns,
+ ntohs (pkt->hdr.size) -
+ sizeof (struct query_packet) + 1,
+ (struct sockaddr *) &dest, sizeof dest);
+ }
+
outfree:
free_parsed_dns_packet (pdns);
pdns = NULL;
@@ -980,7 +1027,40 @@
static void
read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+static void
+read_response6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
static int
+open_port6 ()
+{
+ struct sockaddr_in6 addr;
+
+ dnsout6 = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_DGRAM, 0);
+ if (dnsout6 == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create socket: %m\n");
+ return GNUNET_SYSERR;
+ }
+ memset (&addr, 0, sizeof (struct sockaddr_in6));
+
+ addr.sin6_family = AF_INET6;
+ int err = GNUNET_NETWORK_socket_bind (dnsout6,
+ (struct sockaddr *) &addr,
+ sizeof (struct sockaddr_in6));
+
+ if (err != GNUNET_OK)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not bind a port: %m\n");
+ return GNUNET_SYSERR;
+ }
+
+ GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout6,
+ &read_response6, NULL);
+
+ return GNUNET_YES;
+}
+
+static int
open_port ()
{
struct sockaddr_in addr;
@@ -1018,10 +1098,61 @@
return GNUNET_YES;
}
+void handle_response(struct dns_pkt* dns, struct sockaddr *addr, socklen_t
addrlen, int r);
+
/**
* Read a response-packet of the UDP-Socket
*/
static void
+read_response6 (void *cls
+ __attribute__ ((unused)),
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct sockaddr_in6 addr;
+ socklen_t addrlen = sizeof (addr);
+ int r;
+ int len;
+
+ if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
+ return;
+
+ memset (&addr, 0, sizeof addr);
+
+#ifndef MINGW
+ if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout6), FIONREAD, &len))
+ {
+ (void)open_port6 ();
+ return;
+ }
+#else
+ /* port the code above? */
+ len = 65536;
+#endif
+
+ unsigned char buf[len];
+ struct dns_pkt *dns = (struct dns_pkt *) buf;
+
+ r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
+ (struct sockaddr *) &addr, &addrlen);
+
+ if (r < 0)
+ {
+ (void)open_port6 ();
+ return;
+ }
+
+ struct sockaddr *addr_ = GNUNET_malloc(sizeof addr);
+ memcpy (addr_, &addr, sizeof addr);
+ handle_response(dns, addr_, 4, r);
+
+ GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout6,
+ &read_response6, NULL);
+}
+
+/**
+ * Read a response-packet of the UDP-Socket
+ */
+static void
read_response (void *cls
__attribute__ ((unused)),
const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -1050,14 +1181,14 @@
/* port the code above? */
len = 65536;
#endif
- {
- unsigned char buf[len];
- struct dns_pkt *dns = (struct dns_pkt *) buf;
- r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
- (struct sockaddr *) &addr, &addrlen);
+ unsigned char buf[len];
+ struct dns_pkt *dns = (struct dns_pkt *) buf;
- if (r < 0)
+ r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
+ (struct sockaddr *) &addr, &addrlen);
+
+ if (r < 0)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
"recvfrom");
@@ -1067,86 +1198,112 @@
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Answer to query %d\n",
- ntohs (dns->s.id));
+ struct sockaddr *addr_ = GNUNET_malloc(sizeof addr);
+ memcpy (addr_, &addr, sizeof addr);
+ handle_response(dns, addr_, 4, r);
- if (query_states[dns->s.id].valid == GNUNET_YES)
+ GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout,
+ &read_response, NULL);
+}
+
+void
+handle_response(struct dns_pkt* dns, struct sockaddr *addr, socklen_t addrlen,
int r)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Answer to query %d\n",
+ ntohs (dns->s.id));
+
+
+ if (query_states[dns->s.id].valid == GNUNET_YES)
{
if (query_states[dns->s.id].tunnel != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Answer to query %d for a remote peer!\n",
- ntohs (dns->s.id));
- /* This response should go through a tunnel */
- uint32_t *c =
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Answer to query %d for a remote peer!\n",
+ ntohs (dns->s.id));
+ /* This response should go through a tunnel */
+ uint32_t *c =
GNUNET_malloc (4 + sizeof (struct GNUNET_MESH_Tunnel *) + r);
- *c = r;
- struct GNUNET_MESH_Tunnel **t = (struct GNUNET_MESH_Tunnel **) (c + 1);
+ *c = r;
+ struct GNUNET_MESH_Tunnel **t = (struct GNUNET_MESH_Tunnel **) (c +
1);
- *t = query_states[dns->s.id].tunnel;
- memcpy (t + 1, dns, r);
- if (NULL ==
- GNUNET_MESH_tunnel_get_data (query_states[dns->s.id].tunnel))
- {
- struct GNUNET_MESH_TransmitHandle *th =
- GNUNET_MESH_notify_transmit_ready
(query_states[dns->s.id].tunnel,
- GNUNET_YES,
- 32,
- GNUNET_TIME_UNIT_MINUTES,
- NULL,
- r +
- sizeof (struct
- GNUNET_MessageHeader),
- mesh_send_response, c);
+ *t = query_states[dns->s.id].tunnel;
+ memcpy (t + 1, dns, r);
+ if (NULL ==
+ GNUNET_MESH_tunnel_get_data (query_states[dns->s.id].tunnel))
+ {
+ struct GNUNET_MESH_TransmitHandle *th =
+ GNUNET_MESH_notify_transmit_ready
(query_states[dns->s.id].tunnel,
+ GNUNET_YES,
+ 32,
+ GNUNET_TIME_UNIT_MINUTES,
+ NULL,
+ r +
+ sizeof (struct
+
GNUNET_MessageHeader),
+ mesh_send_response, c);
- GNUNET_MESH_tunnel_set_data (query_states[dns->s.id].tunnel, th);
- }
- else
- {
- struct tunnel_notify_queue *head =
- GNUNET_MESH_tunnel_get_head (query_states[dns->s.id].tunnel);
- struct tunnel_notify_queue *tail =
- GNUNET_MESH_tunnel_get_tail (query_states[dns->s.id].tunnel);
+ GNUNET_MESH_tunnel_set_data (query_states[dns->s.id].tunnel, th);
+ }
+ else
+ {
+ struct tunnel_notify_queue *head =
+ GNUNET_MESH_tunnel_get_head (query_states[dns->s.id].tunnel);
+ struct tunnel_notify_queue *tail =
+ GNUNET_MESH_tunnel_get_tail (query_states[dns->s.id].tunnel);
- struct tunnel_notify_queue *element =
- GNUNET_malloc (sizeof (struct tunnel_notify_queue));
- element->cls = c;
- element->len = r + sizeof (struct GNUNET_MessageHeader);
- element->cb = mesh_send_response;
+ struct tunnel_notify_queue *element =
+ GNUNET_malloc (sizeof (struct tunnel_notify_queue));
+ element->cls = c;
+ element->len = r + sizeof (struct GNUNET_MessageHeader);
+ element->cb = mesh_send_response;
- GNUNET_CONTAINER_DLL_insert_tail (head, tail, element);
- GNUNET_MESH_tunnel_set_head (query_states[dns->s.id].tunnel, head);
- GNUNET_MESH_tunnel_set_tail (query_states[dns->s.id].tunnel, tail);
+ GNUNET_CONTAINER_DLL_insert_tail (head, tail, element);
+ GNUNET_MESH_tunnel_set_head (query_states[dns->s.id].tunnel,
head);
+ GNUNET_MESH_tunnel_set_tail (query_states[dns->s.id].tunnel,
tail);
+ }
}
- }
else
- {
- query_states[dns->s.id].valid = GNUNET_NO;
+ {
+ query_states[dns->s.id].valid = GNUNET_NO;
- size_t len = sizeof (struct answer_packet) + r - 1; /* 1 for the
unsigned char data[1]; */
- struct answer_packet_list *answer =
+ size_t len = sizeof (struct answer_packet) + r - 1; /* 1 for the
unsigned char data[1]; */
+ struct answer_packet_list *answer =
GNUNET_malloc (len + 2 * sizeof (struct answer_packet_list *));
- answer->pkt.hdr.type =
+ answer->pkt.hdr.type =
htons (GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_RESPONSE_DNS);
- answer->pkt.hdr.size = htons (len);
- answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
- answer->pkt.from = addr.sin_addr.s_addr;
- answer->pkt.to = query_states[dns->s.id].local_ip;
- answer->pkt.dst_port = query_states[dns->s.id].local_port;
- memcpy (answer->pkt.data, buf, r);
+ answer->pkt.hdr.size = htons (len);
+ answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
+ answer->pkt.addrlen = addrlen;
+ if (addrlen == 16)
+ {
+ struct sockaddr_in6 *addr_ = (struct sockaddr_in6*)addr;
+ memcpy(answer->pkt.from, &addr_->sin6_addr, addrlen);
+ memcpy(answer->pkt.to, query_states[dns->s.id].local_ip,
addrlen);
+ }
+ else if (addrlen == 4)
+ {
+ struct sockaddr_in *addr_ = (struct sockaddr_in*)addr;
+ memcpy(answer->pkt.from, &addr_->sin_addr.s_addr, addrlen);
+ memcpy(answer->pkt.to, query_states[dns->s.id].local_ip,
addrlen);
+ }
+ else
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "addrlen = %d\n", addrlen);
+ GNUNET_assert(0);
+ }
+ answer->pkt.dst_port = query_states[dns->s.id].local_port;
+ memcpy (answer->pkt.data, dns, r);
- GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer);
+ GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer);
- if (server_notify == NULL)
- server_notify = GNUNET_SERVER_notify_transmit_ready
(query_states[dns->s.id].client,
- len,
GNUNET_TIME_UNIT_FOREVER_REL,
- &send_answer,
-
query_states[dns->s.id].client);
- }
+ if (server_notify == NULL)
+ server_notify = GNUNET_SERVER_notify_transmit_ready
(query_states[dns->s.id].client,
+ len,
GNUNET_TIME_UNIT_FOREVER_REL,
+ &send_answer,
+
query_states[dns->s.id].client);
+ }
}
- }
- GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout,
- &read_response, NULL);
+ GNUNET_free(addr);
}
@@ -1422,6 +1579,11 @@
GNUNET_APPLICATION_TYPE_END
};
+ if (GNUNET_YES != open_port6 ())
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
if (GNUNET_YES != open_port ())
{
Modified: gnunet/src/vpn/gnunet-vpn-packet.h
===================================================================
--- gnunet/src/vpn/gnunet-vpn-packet.h 2011-10-26 00:02:43 UTC (rev 17760)
+++ gnunet/src/vpn/gnunet-vpn-packet.h 2011-10-26 07:13:23 UTC (rev 17761)
@@ -40,8 +40,8 @@
unsigned proto:8 GNUNET_PACKED;
unsigned chks:16 GNUNET_PACKED;
- unsigned sadr:32 GNUNET_PACKED;
- unsigned dadr:32 GNUNET_PACKED;
+ uint32_t sadr GNUNET_PACKED;
+ uint32_t dadr GNUNET_PACKED;
};
#define TCP_FLAG_SYN 2
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r17761 - in gnunet: contrib src/vpn,
gnunet <=