aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2011-06-15 07:15:31 +0000
committerPhilipp Tölke <toelke@in.tum.de>2011-06-15 07:15:31 +0000
commit3c1715418cff7fb0c19dbeb4fa499fd1187db845 (patch)
treeb6a6a43c9989cfbacf2edaf2ee868ea516dddbfb /src/vpn
parentf3810d30c0bc216db587e68cf29c8fd9ab8b2e11 (diff)
downloadgnunet-3c1715418cff7fb0c19dbeb4fa499fd1187db845.tar.gz
gnunet-3c1715418cff7fb0c19dbeb4fa499fd1187db845.zip
send queries on to the internet and send the replies back
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-service-dns.c182
1 files changed, 117 insertions, 65 deletions
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c
index a735788b1..6e194ac73 100644
--- a/src/vpn/gnunet-service-dns.c
+++ b/src/vpn/gnunet-service-dns.c
@@ -83,13 +83,14 @@ static struct answer_packet_list *tail;
83 * some information needed to handle this query 83 * some information needed to handle this query
84 * 84 *
85 * It currently allocates at least 85 * It currently allocates at least
86 * (1 + machine-width + 32 + 32 + 16 + machine-width + 8) * 65536 bit 86 * (1 + machine-width + machine-width + 32 + 32 + 16 + machine-width + 8) * 65536 bit
87 * = 1.7 MiB on 64 bit. 87 * = 17 MiB on 64 bit.
88 * = 1.2 MiB on 32 bit. 88 * = 11 MiB on 32 bit.
89 */ 89 */
90static struct { 90static struct {
91 unsigned valid:1; 91 unsigned valid:1;
92 struct GNUNET_SERVER_Client* client; 92 struct GNUNET_SERVER_Client* client;
93 struct GNUNET_MESH_Tunnel *tunnel;
93 uint32_t local_ip; 94 uint32_t local_ip;
94 uint32_t remote_ip; 95 uint32_t remote_ip;
95 uint16_t local_port; 96 uint16_t local_port;
@@ -202,6 +203,26 @@ struct tunnel_cls {
202 203
203struct tunnel_cls *remote_pending[UINT16_MAX]; 204struct tunnel_cls *remote_pending[UINT16_MAX];
204 205
206static size_t
207mesh_send_response (void *cls, size_t size, void *buf)
208{
209 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
210 struct GNUNET_MessageHeader *hdr = buf;
211 uint32_t *sz = cls;
212 struct dns_pkt *dns = (struct dns_pkt *) (sz + 1);
213 hdr->type = htons (GNUNET_MESSAGE_TYPE_REMOTE_ANSWER_DNS);
214 hdr->size = htons (*sz + sizeof (struct GNUNET_MessageHeader));
215
216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
217 "Sending response, size=%d, sz=%d, sz+hdr=%d\n", size, *sz,
218 *sz + sizeof (struct GNUNET_MessageHeader));
219
220 GNUNET_assert (size >= (*sz + sizeof (struct GNUNET_MessageHeader)));
221
222 memcpy (hdr + 1, dns, *sz);
223 GNUNET_free (cls);
224 return ntohs (hdr->size);
225}
205 226
206static size_t 227static size_t
207mesh_send (void *cls, size_t size, void *buf) 228mesh_send (void *cls, size_t size, void *buf)
@@ -259,6 +280,23 @@ receive_mesh_query (void *cls,
259 const struct GNUNET_MessageHeader *message, 280 const struct GNUNET_MessageHeader *message,
260 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 281 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
261{ 282{
283 struct dns_pkt *dns = (struct dns_pkt*)(message + 1);
284
285 struct sockaddr_in dest;
286 memset(&dest, 0, sizeof dest);
287 dest.sin_port = htons(53);
288 /* TODO: read from config */
289 inet_pton(AF_INET, "8.8.8.8", &dest.sin_addr);
290
291 query_states[dns->s.id].tunnel = tunnel;
292 query_states[dns->s.id].valid = GNUNET_YES;
293
294 GNUNET_NETWORK_socket_sendto(dnsout,
295 dns,
296 ntohs(message->size) - sizeof(struct GNUNET_MessageHeader),
297 (struct sockaddr*) &dest,
298 sizeof dest);
299
262 return GNUNET_SYSERR; 300 return GNUNET_SYSERR;
263} 301}
264 302
@@ -764,75 +802,89 @@ open_port ()
764 * Read a response-packet of the UDP-Socket 802 * Read a response-packet of the UDP-Socket
765 */ 803 */
766static void 804static void
767read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { 805read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
768 struct sockaddr_in addr; 806{
769 socklen_t addrlen = sizeof (addr); 807 struct sockaddr_in addr;
770 int r; 808 socklen_t addrlen = sizeof (addr);
771 int len; 809 int r;
810 int len;
772 811
773 if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) 812 if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
774 return; 813 return;
775 814
776 memset(&addr, 0, sizeof addr); 815 memset (&addr, 0, sizeof addr);
777 816
778#ifndef MINGW 817#ifndef MINGW
779 if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), 818 if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout), FIONREAD, &len))
780 FIONREAD, &len)) 819 {
820 unhijack (dnsoutport);
821 open_port ();
822 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, hijack, NULL);
823 return;
824 }
825#else
826 /* port the code above? */
827 len = 65536;
828#endif
829 {
830 unsigned char buf[len];
831 struct dns_pkt *dns = (struct dns_pkt *) buf;
832
833 r = GNUNET_NETWORK_socket_recvfrom (dnsout,
834 buf,
835 sizeof (buf),
836 (struct sockaddr *) &addr, &addrlen);
837
838 if (r < 0)
781 { 839 {
782 unhijack(dnsoutport); 840 unhijack (dnsoutport);
783 open_port(); 841 open_port ();
784 GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS, hijack, NULL); 842 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, hijack, NULL);
785 return; 843 return;
786 } 844 }
787#else 845
788 /* port the code above? */ 846 if (query_states[dns->s.id].valid == GNUNET_YES)
789 len = 65536; 847 {
790#endif 848 if (query_states[dns->s.id].tunnel != NULL)
791 { 849 {
792 unsigned char buf[len]; 850 uint32_t *c = GNUNET_malloc(4 + r);
793 struct dns_pkt* dns = (struct dns_pkt*)buf; 851 *c = r;
794 852 memcpy(c+1, dns, r);
795 r = GNUNET_NETWORK_socket_recvfrom (dnsout, 853 GNUNET_MESH_notify_transmit_ready (query_states[dns->s.id].tunnel,
796 buf, 854 GNUNET_YES,
797 sizeof (buf), 855 32,
798 (struct sockaddr*)&addr, 856 GNUNET_TIME_UNIT_MINUTES,
799 &addrlen); 857 NULL, r + sizeof(struct GNUNET_MessageHeader), mesh_send_response, c);
800 858 }
801 if (r < 0) 859 else
802 { 860 {
803 unhijack(dnsoutport); 861 query_states[dns->s.id].valid = GNUNET_NO;
804 open_port(); 862
805 GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS, hijack, NULL); 863 size_t len = sizeof (struct answer_packet) + r - 1; /* 1 for the unsigned char data[1]; */
806 return; 864 struct answer_packet_list *answer =
807 } 865 GNUNET_malloc (len + 2 * sizeof (struct answer_packet_list *));
808 866 answer->pkt.hdr.type =
809 if (query_states[dns->s.id].valid == GNUNET_YES) 867 htons (GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS);
810 { 868 answer->pkt.hdr.size = htons (len);
811 query_states[dns->s.id].valid = GNUNET_NO; 869 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
812 870 answer->pkt.from = addr.sin_addr.s_addr;
813 size_t len = sizeof(struct answer_packet) + r - 1; /* 1 for the unsigned char data[1]; */ 871 answer->pkt.to = query_states[dns->s.id].local_ip;
814 struct answer_packet_list* answer = GNUNET_malloc(len + 2*sizeof(struct answer_packet_list*)); 872 answer->pkt.dst_port = query_states[dns->s.id].local_port;
815 answer->pkt.hdr.type = htons(GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS); 873 memcpy (answer->pkt.data, buf, r);
816 answer->pkt.hdr.size = htons(len); 874
817 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP; 875 GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer);
818 answer->pkt.from = addr.sin_addr.s_addr; 876
819 answer->pkt.to = query_states[dns->s.id].local_ip; 877 GNUNET_SERVER_notify_transmit_ready (query_states[dns->s.id].
820 answer->pkt.dst_port = query_states[dns->s.id].local_port; 878 client, len,
821 memcpy(answer->pkt.data, buf, r); 879 GNUNET_TIME_UNIT_FOREVER_REL,
822 880 &send_answer,
823 GNUNET_CONTAINER_DLL_insert_after(head, tail, tail, answer); 881 query_states[dns->s.id].
824 882 client);
825 GNUNET_SERVER_notify_transmit_ready(query_states[dns->s.id].client, 883 }
826 len, 884 }
827 GNUNET_TIME_UNIT_FOREVER_REL, 885 }
828 &send_answer, 886 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
829 query_states[dns->s.id].client); 887 dnsout, &read_response, NULL);
830 }
831 }
832 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
833 dnsout,
834 &read_response,
835 NULL);
836} 888}
837 889
838 890