From 402a25de1ef93133c9879706071081405ade61f6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 1 Jan 2012 23:39:24 +0000 Subject: [PATCH] first quick hack to extract an initial DNS service API --- src/dns/Makefile.am | 12 +- .../gnunet-daemon-vpn-dns.c => dns/dns_api.c} | 218 +++++++++++------- src/include/gnunet_dns_service.h | 26 +++ src/vpn/Makefile.am | 2 +- src/vpn/gnunet-daemon-vpn-dns.h | 88 ------- src/vpn/gnunet-daemon-vpn-helper.c | 36 +-- src/vpn/gnunet-daemon-vpn.c | 21 +- src/vpn/gnunet-daemon-vpn.h | 6 + 8 files changed, 200 insertions(+), 209 deletions(-) rename src/{vpn/gnunet-daemon-vpn-dns.c => dns/dns_api.c} (50%) delete mode 100644 src/vpn/gnunet-daemon-vpn-dns.h diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am index 4eaade330..9e2566bca 100644 --- a/src/dns/Makefile.am +++ b/src/dns/Makefile.am @@ -21,7 +21,9 @@ else install-exec-hook: endif -lib_LTLIBRARIES = libgnunetdnsparser.la +lib_LTLIBRARIES = \ + libgnunetdnsparser.la \ + libgnunetdns.la bin_PROGRAMS = \ gnunet-service-dns $(HIJACKBIN) @@ -45,4 +47,12 @@ libgnunetdnsparser_la_SOURCES = \ libgnunetdnsparser_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la $(XLIB) libgnunetdnsparser_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) + + +libgnunetdns_la_SOURCES = \ + dns_api.c +libgnunetdns_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la $(XLIB) +libgnunetdns_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ No newline at end of file diff --git a/src/vpn/gnunet-daemon-vpn-dns.c b/src/dns/dns_api.c similarity index 50% rename from src/vpn/gnunet-daemon-vpn-dns.c rename to src/dns/dns_api.c index b24d802f7..90b4a8f42 100644 --- a/src/vpn/gnunet-daemon-vpn-dns.c +++ b/src/dns/dns_api.c @@ -33,19 +33,25 @@ #include #include -#include "gnunet-daemon-vpn-dns.h" -#include "gnunet-daemon-vpn.h" -#include "gnunet-daemon-vpn-helper.h" -#include "gnunet-vpn-packet.h" +#include "gnunet_dns_service.h" -struct query_packet_list *head; -struct query_packet_list *tail; -struct GNUNET_CLIENT_Connection *dns_connection; -unsigned char restart_hijack; -struct answer_packet_list *answer_proc_head; -struct answer_packet_list *answer_proc_tail; -struct GNUNET_CLIENT_TransmitHandle *dns_transmit_handle; +struct GNUNET_DNS_Handle +{ + struct query_packet_list *head; + struct query_packet_list *tail; + struct GNUNET_CLIENT_Connection *dns_connection; + unsigned char restart_hijack; + + struct GNUNET_CLIENT_TransmitHandle *dns_transmit_handle; + + const struct GNUNET_CONFIGURATION_Handle *cfg; + + GNUNET_SCHEDULER_Task process_answer_cb; + + void *process_answer_cb_cls; +}; + /** * Callback called by notify_transmit_ready; sends dns-queries or rehijack-messages @@ -55,16 +61,18 @@ struct GNUNET_CLIENT_TransmitHandle *dns_transmit_handle; size_t send_query (void *cls GNUNET_UNUSED, size_t size, void *buf) { + struct GNUNET_DNS_Handle *h = cls; + size_t len; - dns_transmit_handle = NULL; + h->dns_transmit_handle = NULL; /* * Send the rehijack-message */ - if (restart_hijack == 1) + if (h->restart_hijack == 1) { - restart_hijack = 0; + h->restart_hijack = 0; /* * The message is just a header */ @@ -75,9 +83,9 @@ send_query (void *cls GNUNET_UNUSED, size_t size, void *buf) hdr->size = htons (len); hdr->type = htons (GNUNET_MESSAGE_TYPE_REHIJACK); } - else if (head != NULL) + else if (h->head != NULL) { - struct query_packet_list *query = head; + struct query_packet_list *query = h->head; len = ntohs (query->pkt.hdr.size); @@ -85,7 +93,7 @@ send_query (void *cls GNUNET_UNUSED, size_t size, void *buf) memcpy (buf, &query->pkt.hdr, len); - GNUNET_CONTAINER_DLL_remove (head, tail, query); + GNUNET_CONTAINER_DLL_remove (h->head, h->tail, query); GNUNET_free (query); } @@ -98,22 +106,22 @@ send_query (void *cls GNUNET_UNUSED, size_t size, void *buf) /* * Check whether more data is to be sent */ - if (head != NULL) + if (h->head != NULL) { - dns_transmit_handle = - GNUNET_CLIENT_notify_transmit_ready (dns_connection, - ntohs (head->pkt.hdr.size), + h->dns_transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (h->dns_connection, + ntohs (h->head->pkt.hdr.size), GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &send_query, NULL); + GNUNET_YES, &send_query, h); } - else if (restart_hijack == 1) + else if (h->restart_hijack == 1) { - dns_transmit_handle = - GNUNET_CLIENT_notify_transmit_ready (dns_connection, - sizeof (struct + h->dns_transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (h->dns_connection, + sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &send_query, NULL); + GNUNET_YES, &send_query, h); } return len; @@ -122,65 +130,30 @@ send_query (void *cls GNUNET_UNUSED, size_t size, void *buf) /* }}} */ -/** - * Connect to the service-dns - */ -void -connect_to_service_dns (void *cls GNUNET_UNUSED, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - conn_task = GNUNET_SCHEDULER_NO_TASK; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to service-dns\n"); - GNUNET_assert (dns_connection == NULL); - dns_connection = GNUNET_CLIENT_connect ("dns", cfg); - /* This would most likely be a misconfiguration */ - GNUNET_assert (NULL != dns_connection); - GNUNET_CLIENT_receive (dns_connection, &dns_answer_handler, NULL, - GNUNET_TIME_UNIT_FOREVER_REL); - - /* We might not yet be connected. Yay, mps. */ - if (NULL == dns_connection) - return; - - /* If a packet is already in the list, schedule to send it */ - if (dns_transmit_handle == NULL && head != NULL) - dns_transmit_handle = - GNUNET_CLIENT_notify_transmit_ready (dns_connection, - ntohs (head->pkt.hdr.size), - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &send_query, NULL); - else if (dns_transmit_handle == NULL && restart_hijack == 1) - { - dns_transmit_handle = - GNUNET_CLIENT_notify_transmit_ready (dns_connection, - sizeof (struct - GNUNET_MessageHeader), - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &send_query, NULL); - } -} /** * This receives packets from the service-dns and schedules process_answer to * handle it */ -void -dns_answer_handler (void *cls GNUNET_UNUSED, +static void +dns_answer_handler (void *cls, const struct GNUNET_MessageHeader *msg) { + struct GNUNET_DNS_Handle *h = cls; + /* the service disconnected, reconnect after short wait */ if (msg == NULL) { - if (dns_transmit_handle != NULL) - GNUNET_CLIENT_notify_transmit_ready_cancel (dns_transmit_handle); - dns_transmit_handle = NULL; - GNUNET_CLIENT_disconnect (dns_connection, GNUNET_NO); - dns_connection = NULL; - conn_task = + if (h->dns_transmit_handle != NULL) + GNUNET_CLIENT_notify_transmit_ready_cancel (h->dns_transmit_handle); + h->dns_transmit_handle = NULL; + GNUNET_CLIENT_disconnect (h->dns_connection, GNUNET_NO); + h->dns_connection = NULL; +#if 0 + h->conn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &connect_to_service_dns, NULL); + &connect_to_service_dns, h); +#endif return; } @@ -188,16 +161,103 @@ dns_answer_handler (void *cls GNUNET_UNUSED, if (msg->type != htons (GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_RESPONSE_DNS)) { GNUNET_break (0); - GNUNET_CLIENT_disconnect (dns_connection, GNUNET_NO); - dns_connection = NULL; + GNUNET_CLIENT_disconnect (h->dns_connection, GNUNET_NO); + h->dns_connection = NULL; +#if 0 conn_task = GNUNET_SCHEDULER_add_now (&connect_to_service_dns, NULL); +#endif return; } void *pkt = GNUNET_malloc (ntohs (msg->size)); memcpy (pkt, msg, ntohs (msg->size)); - GNUNET_SCHEDULER_add_now (process_answer, pkt); - GNUNET_CLIENT_receive (dns_connection, &dns_answer_handler, NULL, + GNUNET_SCHEDULER_add_now (h->process_answer_cb, pkt); + GNUNET_CLIENT_receive (h->dns_connection, &dns_answer_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); } + + +/** + * Connect to the service-dns + */ +struct GNUNET_DNS_Handle * +GNUNET_DNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_SCHEDULER_Task cb, + void *cb_cls) +{ + struct GNUNET_DNS_Handle *h; + + h = GNUNET_malloc (sizeof (struct GNUNET_DNS_Handle)); + h->cfg = cfg; + h->process_answer_cb = cb; + h->process_answer_cb_cls = cb_cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to service-dns\n"); + h->dns_connection = GNUNET_CLIENT_connect ("dns", h->cfg); + /* This would most likely be a misconfiguration */ + GNUNET_assert (NULL != h->dns_connection); + GNUNET_CLIENT_receive (h->dns_connection, + &dns_answer_handler, NULL, + GNUNET_TIME_UNIT_FOREVER_REL); + /* If a packet is already in the list, schedule to send it */ + if (h->dns_transmit_handle == NULL && h->head != NULL) + h->dns_transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (h->dns_connection, + ntohs (h->head->pkt.hdr.size), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &send_query, h); + else if (h->dns_transmit_handle == NULL && h->restart_hijack == 1) + { + h->dns_transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (h->dns_connection, + sizeof (struct + GNUNET_MessageHeader), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &send_query, NULL); + } + return h; +} + + +void +GNUNET_DNS_restart_hijack (struct GNUNET_DNS_Handle *h) +{ + h->restart_hijack = 1; + if (NULL != h->dns_connection && h->dns_transmit_handle == NULL) + h->dns_transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (h->dns_connection, + sizeof (struct + GNUNET_MessageHeader), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &send_query, h); +} + + +/** + * FIXME: we should not expost our internal structures like this. + * Just a quick initial hack. + */ +void +GNUNET_DNS_queue_request (struct GNUNET_DNS_Handle *h, + struct query_packet_list *q) +{ + GNUNET_CONTAINER_DLL_insert_tail (h->head, h->tail, q); + if (h->dns_connection != NULL && h->dns_transmit_handle == NULL) + h->dns_transmit_handle = + GNUNET_CLIENT_notify_transmit_ready (h->dns_connection, ntohs(q->pkt.hdr.size), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, &send_query, + h); +} + + +void +GNUNET_DNS_disconnect (struct GNUNET_DNS_Handle *h) +{ + if (h->dns_connection != NULL) + { + GNUNET_CLIENT_disconnect (h->dns_connection, GNUNET_NO); + h->dns_connection = NULL; + } + GNUNET_free (h); +} diff --git a/src/include/gnunet_dns_service.h b/src/include/gnunet_dns_service.h index 2423009eb..4dcf6c375 100644 --- a/src/include/gnunet_dns_service.h +++ b/src/include/gnunet_dns_service.h @@ -29,6 +29,7 @@ #define GNUNET_DNS_SERVICE_H #include "gnunet_common.h" +#include "gnunet_util_lib.h" GNUNET_NETWORK_STRUCT_BEGIN @@ -140,4 +141,29 @@ struct answer_packet_list }; GNUNET_NETWORK_STRUCT_END +struct GNUNET_DNS_Handle; + +/** + * Connect to the service-dns + */ +struct GNUNET_DNS_Handle * +GNUNET_DNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_SCHEDULER_Task cb, + void *cb_cls); + +void +GNUNET_DNS_restart_hijack (struct GNUNET_DNS_Handle *h); + + +/** + * FIXME: we should not expost our internal structures like this. + * Just a quick initial hack. + */ +void +GNUNET_DNS_queue_request (struct GNUNET_DNS_Handle *h, + struct query_packet_list *q); + +void +GNUNET_DNS_disconnect (struct GNUNET_DNS_Handle *h); + #endif diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index dfba44f0a..13928dba3 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am @@ -35,7 +35,6 @@ gnunet_helper_vpn_SOURCES = \ gnunet_daemon_vpn_SOURCES = \ gnunet-daemon-vpn.c gnunet-daemon-vpn.h \ gnunet-daemon-vpn-helper.c gnunet-daemon-vpn-helper.h \ - gnunet-daemon-vpn-dns.c gnunet-daemon-vpn-dns.h \ gnunet-helper-vpn-api.c gnunet-helper-vpn-api.h \ gnunet-vpn-checksum.c gnunet-vpn-checksum.h gnunet_daemon_vpn_LDADD = \ @@ -44,6 +43,7 @@ gnunet_daemon_vpn_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/mesh/libgnunetmesh.la \ $(top_builddir)/src/dns/libgnunetdnsparser.la \ + $(top_builddir)/src/dns/libgnunetdns.la \ $(GN_LIBINTL) gnunet_daemon_exit_SOURCES = \ diff --git a/src/vpn/gnunet-daemon-vpn-dns.h b/src/vpn/gnunet-daemon-vpn-dns.h deleted file mode 100644 index 0cd0d8b26..000000000 --- a/src/vpn/gnunet-daemon-vpn-dns.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2010 Christian Grothoff - - 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 3, 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 vpn/gnunet-daemon-vpn-dns.h - * @brief - * @author Philipp Toelke - */ -#ifndef GNUNET_DAEMON_VPN_DNS_H -#define GNUNET_DAEMON_VPN_DNS_H - -/** - * a list of outgoing dns-query-packets - */ -extern struct query_packet_list *head; - -/** - * The last element of the list of outgoing dns-query-packets - */ -extern struct query_packet_list *tail; - -/** - * Callback called by notify_transmit_ready; sends dns-queries or rehijack-messages - * to the service-dns - */ -size_t -send_query (void *cls, size_t size, void *buf); - -/** - * Connect to the service-dns - */ -void -connect_to_service_dns (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * This receives packets from the service-dns and schedules process_answer to - * handle it - */ -void -dns_answer_handler (void *cls, const struct GNUNET_MessageHeader *msg); - -/** - * The connection to the service-dns - */ -extern struct GNUNET_CLIENT_Connection *dns_connection; - -/** - * A flag to show that the service-dns has to rehijack the outbound dns-packets - * - * This gets set when the helper restarts as the routing-tables are flushed when - * the interface vanishes. - */ -extern unsigned char restart_hijack; - -/** - * A list of processed dns-responses. - * - * "processed" means that the packet is complete and can be sent out via udp - * directly - */ -extern struct answer_packet_list *answer_proc_head; - -/** - * The last element of the list of processed dns-responses. - */ -extern struct answer_packet_list *answer_proc_tail; - -extern GNUNET_SCHEDULER_TaskIdentifier conn_task; - -#endif /* end of include guard: GNUNET-DAEMON-VPN-DNS_H */ diff --git a/src/vpn/gnunet-daemon-vpn-helper.c b/src/vpn/gnunet-daemon-vpn-helper.c index 8f295506a..984b126e7 100644 --- a/src/vpn/gnunet-daemon-vpn-helper.c +++ b/src/vpn/gnunet-daemon-vpn-helper.c @@ -34,8 +34,8 @@ #include #include #include +#include -#include "gnunet-daemon-vpn-dns.h" #include "gnunet-daemon-vpn.h" #include "gnunet-daemon-vpn-helper.h" #include "gnunet-vpn-packet.h" @@ -137,15 +137,7 @@ start_helper_and_schedule (void *cls, /* Tell the dns-service to rehijack the dns-port * The routing-table gets flushed if an interface disappears. */ - restart_hijack = 1; - if (NULL != dns_connection && dns_transmit_handle == NULL) - dns_transmit_handle = - GNUNET_CLIENT_notify_transmit_ready (dns_connection, - sizeof (struct - GNUNET_MessageHeader), - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &send_query, NULL); - + GNUNET_DNS_restart_hijack (dns_handle); GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, helper_handle->fh_to_helper, &helper_write, NULL); @@ -361,17 +353,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, 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); + GNUNET_DNS_queue_request (dns_handle, query); break; } /* fall through */ @@ -559,16 +541,8 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, query->pkt.addrlen = 4; query->pkt.src_port = udp->udp_hdr.spt; memcpy (query->pkt.data, udp->data, ntohs (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); + + GNUNET_DNS_queue_request (dns_handle, query); } else { diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 6b65b709e..86f08d19c 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -36,7 +36,7 @@ #include "gnunet_constants.h" #include #include "gnunet-daemon-vpn-helper.h" -#include "gnunet-daemon-vpn-dns.h" +#include "gnunet_dns_service.h" #include "gnunet-daemon-vpn.h" #include "gnunet-vpn-checksum.h" @@ -45,6 +45,13 @@ struct GNUNET_MESH_Handle *mesh_handle; struct GNUNET_CONTAINER_MultiHashMap *hashmap; static struct GNUNET_CONTAINER_Heap *heap; +struct GNUNET_DNS_Handle *dns_handle; + +struct answer_packet_list *answer_proc_head; + +struct answer_packet_list *answer_proc_tail; + + struct tunnel_notify_queue { struct tunnel_notify_queue *next; @@ -87,12 +94,7 @@ cleanup (void *cls GNUNET_UNUSED, cleanup_helper (helper_handle); /* close the connection to the service-dns */ - if (dns_connection != NULL) - { - GNUNET_CLIENT_disconnect (dns_connection, GNUNET_NO); - dns_connection = NULL; - } - + GNUNET_DNS_disconnect (dns_handle); if (mesh_handle != NULL) { GNUNET_MESH_disconnect (mesh_handle); @@ -1258,13 +1260,14 @@ run (void *cls, char *const *args GNUNET_UNUSED, GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers, types); cfg = cfg_; - restart_hijack = 0; hashmap = GNUNET_CONTAINER_multihashmap_create (65536); heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPINGg", &max_mappings); udp_connections = GNUNET_CONTAINER_multihashmap_create (65536); - conn_task = GNUNET_SCHEDULER_add_now (connect_to_service_dns, NULL); + dns_handle = GNUNET_DNS_connect (cfg, + &process_answer, + NULL); shs_task = GNUNET_SCHEDULER_add_after (conn_task, start_helper_and_schedule, NULL); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); diff --git a/src/vpn/gnunet-daemon-vpn.h b/src/vpn/gnunet-daemon-vpn.h index c8bf91ebb..35520a277 100644 --- a/src/vpn/gnunet-daemon-vpn.h +++ b/src/vpn/gnunet-daemon-vpn.h @@ -28,6 +28,12 @@ #include "gnunet_dns_service.h" +extern struct answer_packet_list *answer_proc_head; + +extern struct answer_packet_list *answer_proc_tail; + +extern struct GNUNET_DNS_Handle *dns_handle; + /** * This gets scheduled with cls pointing to an answer_packet and does everything * needed in order to send it to the helper. -- 2.25.1