X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fvpn%2Fgnunet-daemon-vpn-dns.c;h=77d9000469f532cd65be29b49eab4f50f8b84449;hb=83b19539f4d322b43683f5838b72e9ec2c8e6073;hp=46ec6d659939b6da1bbeb0eb34614681b0acdaa6;hpb=e300436fe55b9d9c359fb99f5fbe9391150fddd0;p=oweals%2Fgnunet.git diff --git a/src/vpn/gnunet-daemon-vpn-dns.c b/src/vpn/gnunet-daemon-vpn-dns.c index 46ec6d659..77d900046 100644 --- a/src/vpn/gnunet-daemon-vpn-dns.c +++ b/src/vpn/gnunet-daemon-vpn-dns.c @@ -46,62 +46,80 @@ 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; + /** * Callback called by notify_transmit_ready; sends dns-queries or rehijack-messages * to the service-dns * {{{ */ size_t -send_query(void* cls __attribute__((unused)), size_t size, void* buf) { - size_t len; - /* - * Send the rehijack-message - */ - if (restart_hijack == 1) - { - restart_hijack = 0; - /* - * The message is just a header - */ - GNUNET_assert(sizeof(struct GNUNET_MessageHeader) <= size); - struct GNUNET_MessageHeader* hdr = buf; - len = sizeof(struct GNUNET_MessageHeader); - hdr->size = htons(len); - hdr->type = htons(GNUNET_MESSAGE_TYPE_REHIJACK); - } - else if (head != NULL) - { - struct query_packet_list* query = head; - len = ntohs(query->pkt.hdr.size); - - GNUNET_assert(len <= size); - - memcpy(buf, &query->pkt.hdr, len); - - GNUNET_CONTAINER_DLL_remove (head, tail, query); - - GNUNET_free(query); - } - else - { - GNUNET_break(0); - len = 0; - } - +send_query (void *cls __attribute__ ((unused)), size_t size, void *buf) +{ + size_t len; + + dns_transmit_handle = NULL; + + /* + * Send the rehijack-message + */ + if (restart_hijack == 1) + { + restart_hijack = 0; /* - * Check whether more data is to be sent + * The message is just a header */ - if (head != NULL) - { - GNUNET_CLIENT_notify_transmit_ready(dns_connection, ntohs(head->pkt.hdr.size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &send_query, NULL); - } - else if (restart_hijack == 1) - { - GNUNET_CLIENT_notify_transmit_ready(dns_connection, sizeof(struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &send_query, NULL); - } - - return len; + GNUNET_assert (sizeof (struct GNUNET_MessageHeader) <= size); + struct GNUNET_MessageHeader *hdr = buf; + + len = sizeof (struct GNUNET_MessageHeader); + hdr->size = htons (len); + hdr->type = htons (GNUNET_MESSAGE_TYPE_REHIJACK); + } + else if (head != NULL) + { + struct query_packet_list *query = head; + + len = ntohs (query->pkt.hdr.size); + + GNUNET_assert (len <= size); + + memcpy (buf, &query->pkt.hdr, len); + + GNUNET_CONTAINER_DLL_remove (head, tail, query); + + GNUNET_free (query); + } + else + { + GNUNET_break (0); + len = 0; + } + + /* + * Check whether more data is to be sent + */ + if (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 (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); + } + + return len; } + /* }}} */ @@ -109,32 +127,41 @@ send_query(void* cls __attribute__((unused)), size_t size, void* buf) { * Connect to the service-dns */ void -connect_to_service_dns (void *cls __attribute__((unused)), - const struct GNUNET_SCHEDULER_TaskContext *tc) { - 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 (head != NULL) - GNUNET_CLIENT_notify_transmit_ready(dns_connection, - ntohs(head->pkt.hdr.size), - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, - &send_query, - NULL); - else if (restart_hijack == 1) - { - GNUNET_CLIENT_notify_transmit_ready(dns_connection, sizeof(struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &send_query, NULL); - } +connect_to_service_dns (void *cls + __attribute__ ((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); + } } /** @@ -142,33 +169,38 @@ connect_to_service_dns (void *cls __attribute__((unused)), * handle it */ void -dns_answer_handler(void* cls __attribute__((unused)), const struct GNUNET_MessageHeader *msg) { - /* the service disconnected, reconnect after short wait */ - if (msg == NULL) - { - GNUNET_CLIENT_disconnect(dns_connection, GNUNET_NO); - dns_connection = NULL; - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &connect_to_service_dns, - NULL); - return; - } - - /* the service did something strange, reconnect immediately */ - if (msg->type != htons(GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS)) - { - GNUNET_break (0); - GNUNET_CLIENT_disconnect(dns_connection, GNUNET_NO); - dns_connection = NULL; - GNUNET_SCHEDULER_add_now (&connect_to_service_dns, - NULL); - 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_TIME_UNIT_FOREVER_REL); +dns_answer_handler (void *cls + __attribute__ ((unused)), + const struct GNUNET_MessageHeader *msg) +{ + /* 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 = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &connect_to_service_dns, NULL); + return; + } + + /* the service did something strange, reconnect immediately */ + 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; + conn_task = GNUNET_SCHEDULER_add_now (&connect_to_service_dns, NULL); + 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_TIME_UNIT_FOREVER_REL); } -