1 /**
2 * \file
3 * unit tests for getdns_dict helper routines, these should be used to
4 * perform regression tests, output must be unchanged from canonical output
5 * stored with the sources
6 */
7
8 /*
9 * Copyright (c) 2013, NLNet Labs, Verisign, Inc.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * * Neither the names of the copyright holders nor the
20 * names of its contributors may be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include "config.h"
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include "testmessages.h"
40 #include "getdns/getdns.h"
41 #include "getdns/getdns_extra.h"
42 #include <sys/time.h>
43
44 #define TRANSPORT_UDP "udp"
45 #define TRANSPORT_UDP_TCP "udp_tcp"
46 #define TRANSPORT_TCP "tcp"
47 #define TRANSPORT_PIPELINE "pipeline"
48 #define TRANSPORT_TLS_KEEPOPEN "tls"
49 #define TRANSPORT_TLS_TCP_KEEPOPEN "dns-over-tls"
50 #define RESOLUTION_STUB "stub"
51 #define RESOLUTION_REC "rec"
52
53 /* Set up the callback function, which will also do the processing of the results */
54 void
this_callbackfn(struct getdns_context * this_context,getdns_callback_type_t this_callback_type,struct getdns_dict * this_response,void * this_userarg,getdns_transaction_t this_transaction_id)55 this_callbackfn(struct getdns_context *this_context,
56 getdns_callback_type_t this_callback_type,
57 struct getdns_dict *this_response,
58 void *this_userarg, getdns_transaction_t this_transaction_id)
59 {
60 (void)this_context; (void)this_userarg;
61
62 if (this_callback_type == GETDNS_CALLBACK_COMPLETE) { /* This is a callback with data */
63 char *res = getdns_pretty_print_dict(this_response);
64 fprintf(stdout, "%s\n", res);
65 free(res);
66
67 } else if (this_callback_type == GETDNS_CALLBACK_CANCEL)
68 fprintf(stderr,
69 "The callback with ID %llu was cancelled. Exiting.\n",
70 (unsigned long long)this_transaction_id);
71 else
72 fprintf(stderr,
73 "The callback got a callback_type of %d. Exiting.\n",
74 this_callback_type);
75 getdns_dict_destroy(this_response);
76 }
77
78 int
main(int argc,char ** argv)79 main(int argc, char** argv)
80 {
81
82 const char *transport = argc > 2 ? argv[2] : "udp_tcp";
83 const char *resolution = argc > 3 ? argv[3] : "stub";
84
85 /* Create the DNS context for this call */
86 struct getdns_context *this_context = NULL;
87 getdns_return_t return_value =
88 getdns_context_create(&this_context, 1);
89 if (return_value != GETDNS_RETURN_GOOD) {
90 fprintf(stderr, "Trying to create the context failed: %d",
91 return_value);
92 return (GETDNS_RETURN_GENERIC_ERROR);
93 }
94
95 if (strncmp(resolution, RESOLUTION_STUB, 4) == 0)
96 getdns_context_set_resolution_type(this_context, GETDNS_RESOLUTION_STUB);
97 else if (strncmp(resolution, RESOLUTION_REC, 4) != 0) {
98 fprintf(stderr, "Invalid resolution %s, must be one of stub or rec\n", transport);
99 exit(EXIT_FAILURE);
100 }
101
102 /* Order matters*/
103 if (strncmp(transport, TRANSPORT_TCP, 3) == 0)
104 getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
105 else if (strncmp(transport, TRANSPORT_UDP_TCP, 7) == 0)
106 getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
107 else if (strncmp(transport, TRANSPORT_UDP, 3) == 0)
108 getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_UDP_ONLY);
109 else if (strncmp(transport, TRANSPORT_PIPELINE, 8) == 0)
110 getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN);
111 else if (strncmp(transport, TRANSPORT_TLS_KEEPOPEN, 3) == 0)
112 getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
113 else if (strncmp(transport, TRANSPORT_TLS_TCP_KEEPOPEN, 12) == 0)
114 getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
115 else if (strncmp(transport, TRANSPORT_UDP_TCP, 3) != 0) {
116 fprintf(stderr, "Invalid transport %s, must be one of udp, udp_tcp, tcp or pipeline\n", transport);
117 exit(EXIT_FAILURE);
118 }
119
120 getdns_context_set_timeout(this_context, 5000);
121 /* Create an event base and put it in the context using the unknown function name */
122 /* Set up the getdns call */
123 const char *this_name = argc > 1 ? argv[1] : "getdnsapi.net";
124 char *this_userarg = "somestring"; // Could add things here to help identify this call
125 getdns_transaction_t this_transaction_id = 0;
126
127 /* Make the call */
128 getdns_return_t dns_request_return =
129 getdns_address(this_context, this_name,
130 NULL, this_userarg, &this_transaction_id, this_callbackfn);
131 if (dns_request_return == GETDNS_RETURN_BAD_DOMAIN_NAME) {
132 fprintf(stderr, "A bad domain name was used: %s. Exiting.",
133 this_name);
134 getdns_context_destroy(this_context);
135 return (GETDNS_RETURN_GENERIC_ERROR);
136 }
137 else {
138 getdns_context_run(this_context);
139 }
140
141 getdns_transport_t get_transport;
142 return_value = getdns_context_get_dns_transport(this_context, &get_transport);
143 if (return_value != GETDNS_RETURN_GOOD) {
144 fprintf(stderr, "Trying to get transport type failed: %d\n",
145 return_value);
146 return (GETDNS_RETURN_GENERIC_ERROR);
147 }
148 fprintf(stderr, "Transport type is %d\n", get_transport);
149
150 size_t transport_count = 0;
151 getdns_transport_list_t *get_transport_list;
152 return_value = getdns_context_get_dns_transport_list(this_context, &transport_count, &get_transport_list);
153 if (return_value != GETDNS_RETURN_GOOD) {
154 fprintf(stderr, "Trying to get transport type failed: %d\n",
155 return_value);
156 return (GETDNS_RETURN_GENERIC_ERROR);
157 }
158 size_t i;
159 for (i = 0; i < transport_count; i++) {
160 fprintf(stderr, "Transport %d is %d\n", (int)i, get_transport_list[i]);
161 }
162 free(get_transport_list);
163
164 /* Clean up */
165 getdns_context_destroy(this_context);
166 /* Assuming we get here, leave gracefully */
167 exit(EXIT_SUCCESS);
168 } /* main */
169
170 /* tests_stub_async.c */
171