From 46748c9a0c8c630d59cf209759073a4b0b6f9ed8 Mon Sep 17 00:00:00 2001
From: saradickinson <sara@sinodun.com>
Date: Wed, 17 Sep 2014 18:24:07 +0000
Subject: [PATCH] Housekeeping of ldns res. Fix transport test.

---
 src/context.c                     | 22 +++++++-------
 src/test/check_getdns_transport.c | 48 +++++++++++++++++--------------
 src/test/tests_stub_sync.c        |  2 +-
 3 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/src/context.c b/src/context.c
index 25dc49c0..0d7b926e 100755
--- a/src/context.c
+++ b/src/context.c
@@ -494,6 +494,8 @@ getdns_context_create_with_extended_memory_functions(
         getdns_context_destroy(result);
         return GETDNS_RETURN_GENERIC_ERROR;
     }
+    /* ldns context is initialised to NULL here and rebuilt later if needed */
+	result->ldns_res = NULL;
 
     *context = result;
 
@@ -577,9 +579,11 @@ getdns_context_destroy(struct getdns_context *context)
     getdns_list_destroy(context->dnssec_trust_anchors);
     getdns_list_destroy(context->upstream_list);
 
-    /* destroy the ub context */
+    /* destroy the contexts */
     if (context->unbound_ctx)
         ub_ctx_delete(context->unbound_ctx);
+    if (context->ldns_res)
+        ldns_resolver_deep_free(context->ldns_res);
 
     if (context->outbound_requests)
         GETDNS_FREE(context->my_mf, context->outbound_requests);
@@ -667,18 +671,16 @@ rebuild_ldns_res(struct getdns_context* context) {
         return GETDNS_RETURN_MEMORY_ERROR;
     }
 
-    /* TODO: Don't think ldns supports this option currently
-     *  set_ldns_dnssec_allowed_skew(context,
-     *        context->dnssec_allowed_skew);
-     */
+    /* TODO: ldns doesn't support this option so this will have to be taken
+             account expliticly during the ldns validation
+     *  set_ldns_dnssec_allowed_skew();*/
+
+    /* This is all the settings required for stub operation in sync mode.
+     * Will need additional work here when supporting async mode.*/
     set_ldns_edns_maximum_udp_payload_size(context,
         context->edns_maximum_udp_payload_size);
     set_ldns_dns_transport(context, context->dns_transport);
 
-    /* Also need to check any other settings that might have been 
-     * and make sure they get set until we have changed all the get/set 
-     * methods */
-
     /* We need to set up the upstream recursive servers from the context */
     set_ldns_nameservers(context, context->upstream_list);
     return GETDNS_RETURN_GOOD;
@@ -1529,7 +1531,7 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
 		switch (context->namespaces[i]) {
 		case GETDNS_NAMESPACE_LOCALNAMES:
 			/* TODO: Note to self! This must change once we have
-			 * asynchronous stub mode using ldns. */
+			 * proper namespace hanlding or asynch stub mode using ldns.*/
 			(void) ub_ctx_hosts(context->unbound_ctx, NULL);
 			break;
 
diff --git a/src/test/check_getdns_transport.c b/src/test/check_getdns_transport.c
index 7a942c69..1717ce47 100755
--- a/src/test/check_getdns_transport.c
+++ b/src/test/check_getdns_transport.c
@@ -103,26 +103,32 @@ void* run_transport_server(void* data) {
         n = read(conn, mesg, 65536);
         tcp_count++;
       }
+
       ldns_wire2pkt(&query, mesg, n);
       ldns_resolver_send_pkt(&pkt, resolver, query);
       ldns_str2rdf_a(&answerfrom, "127.0.0.1");
       ldns_pkt_set_answerfrom(pkt, answerfrom);
       ldns_pkt_free(query);
-      uint8_t* pkt_data;
-      size_t pkt_len;
-      ldns_pkt* answer = pkt;
-      ldns_pkt2wire(&pkt_data, answer, &pkt_len);
+
+      ldns_buffer *send_buf;
+      send_buf = ldns_buffer_new(LDNS_MIN_BUFLEN);
+      ldns_pkt2buffer_wire(send_buf, pkt);
+
       if (udp_count > 0) {
-        sendto(udp, pkt_data, pkt_len, 0, (struct sockaddr *) &client_addr, sizeof (client_addr));
+        sendto(udp, (void*)ldns_buffer_begin(send_buf), ldns_buffer_position(send_buf), 
+                0, (struct sockaddr *) &client_addr, sizeof (client_addr));
       } else if (conn > 0) {
-        int wcount = write(conn, pkt_data, pkt_len);
-        if (wcount != pkt_len) {
-          /* For now ignore this */
-          continue;
-        }
+        uint8_t *send_array;
+        /* add length of packet */
+        send_array = LDNS_XMALLOC(uint8_t, ldns_buffer_position(send_buf) + 2);
+        if(!send_array) return 0;
+        ldns_write_uint16(send_array, ldns_buffer_position(send_buf));
+        memcpy(send_array + 2, ldns_buffer_begin(send_buf), ldns_buffer_position(send_buf));
+        write(conn, (void*)send_array, ldns_buffer_position(send_buf) + 2);
+        LDNS_FREE(send_array);
       }
-      free(pkt_data);
-      ldns_pkt_free(answer);
+      LDNS_FREE(send_buf);
+      ldns_pkt_free(pkt);
     } /* End of if */
   } /* end of while loop */
   close(udp);
@@ -210,7 +216,7 @@ START_TEST(getdns_transport_udp_sync) {
 
   t_data.running = 0;
   pthread_join(thread, NULL);
-  ck_assert_msg(t_data.udp_count == 1, "udp_count != 1");
+  ck_assert_msg(t_data.udp_count >= 1, "udp_count !>= 1");
   ck_assert_msg(t_data.tcp_count == 0, "tcp_count != 0");
 
 }
@@ -285,7 +291,7 @@ START_TEST(getdns_transport_tcp_sync) {
   t_data.running = 0;
   pthread_join(thread, NULL);
   ck_assert_msg(t_data.udp_count == 0, "udp_count != 0");
-  ck_assert_msg(t_data.tcp_count == 1, "tcp_count != 1");
+  ck_assert_msg(t_data.tcp_count >= 1, "tcp_count !>= 1");
 
 }
 
@@ -362,7 +368,7 @@ START_TEST(getdns_transport_udp_async) {
 
   t_data.running = 0;
   pthread_join(thread, NULL);
-  ck_assert_msg(t_data.udp_count == 1, "udp_count != 1");
+  ck_assert_msg(t_data.udp_count >= 1, "udp_count !>= 1");
   ck_assert_msg(t_data.tcp_count == 0, "tcp_count != 0");
 
 }
@@ -441,7 +447,7 @@ START_TEST(getdns_transport_tcp_async) {
   t_data.running = 0;
   pthread_join(thread, NULL);
   ck_assert_msg(t_data.udp_count == 0, "udp_count != 0");
-  ck_assert_msg(t_data.tcp_count == 1, "tcp_count != 1");
+  ck_assert_msg(t_data.tcp_count >= 1, "tcp_count !>= 1");
 
 }
 
@@ -454,12 +460,10 @@ Suite *
 getdns_transport_suite(void) {
   Suite *s = suite_create("getdns_transport()");
 
-  /*TODO: The sync tests will fail if root keys are configured! 
-   * Unbound does DNSSEC even if the extention is not set if 
-   * it has root keys. This seems very inefficient....! 
-   * Need to either unset the root keys during this test
-   * or detect the correct number of responses based on
-   * DNS vs DNSSEC.*/
+  /* Note that the exact number of messages received depends on if a trust
+   * anchor is configured so these tests just check that no messages are
+   * received on the wrong transport and at least one is recieved on the
+   * expected transport */
 
   /* Positive test cases */
   TCase *tc_pos = tcase_create("Positive");
diff --git a/src/test/tests_stub_sync.c b/src/test/tests_stub_sync.c
index c664015d..b8366c55 100755
--- a/src/test/tests_stub_sync.c
+++ b/src/test/tests_stub_sync.c
@@ -83,7 +83,7 @@ main()
 	getdns_dict_destroy(response);
 	
 	/* Now switch to TCP and make sure everything works */
-    getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
+	getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
 	
 	ret = getdns_general_sync(this_context, "www.google.com", GETDNS_RRTYPE_A,
 	                          NULL, &response);