Fawkes API Fawkes Development Version
qa_resolver.cpp
1
2/***************************************************************************
3 * qa_resolver.cpp - Fawkes QA for resolver
4 *
5 * Created: Thu May 10 19:10:03 2007
6 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24/// @cond QA
25
26#include <netcomm/utils/resolver.h>
27#include <utils/system/argparser.h>
28#include <utils/system/signal.h>
29#ifdef HAVE_AVAHI
30# include <netcomm/dns-sd/avahi_thread.h>
31#endif
32
33#include <arpa/inet.h>
34#include <netinet/in.h>
35
36#include <cstdio>
37#include <cstdlib>
38#include <cstring>
39
40using namespace fawkes;
41
42class ResolverQAMain : public SignalHandler
43{
44public:
45 ResolverQAMain(ArgumentParser *argp)
46 {
47 this->argp = argp;
48 quit = false;
49
50 r = NULL;
51
52#ifdef HAVE_AVAHI
53 at = NULL;
54 if (argp->has_arg("a")) {
55 printf("Instantiating Avahi thread\n");
56 at = new AvahiThread();
57 at->start();
58 at->wait_initialized();
59 usleep(0);
60 }
61 r = new NetworkNameResolver(at);
62#else
63 if (argp->has_arg("a")) {
64 printf("Avahi not available at compile time\n");
65 }
66 r = new NetworkNameResolver();
67#endif
68 }
69
70 ~ResolverQAMain()
71 {
72#ifdef HAVE_AVAHI
73 if (at != NULL) {
74 at->cancel();
75 at->join();
76 delete at;
77 }
78#endif
79 delete r;
80 }
81
82 void
83 run()
84 {
85 struct sockaddr_in *s = NULL;
86 socklen_t slen;
87
88 char *test = (char *)malloc(strlen("127.0.0.1") + 1);
89 strcpy(test, "127.0.0.1");
90 r->resolve_name(test, (struct sockaddr **)&s, &slen);
91 free(test);
92
93 while (!quit && !r->resolve_name("127.0.0.1", (struct sockaddr **)&s, &slen)) {
94 usleep(0);
95 }
96 if (quit) {
97 return;
98 }
99 printf("Successfully resolved to 0x%x\n", s->sin_addr.s_addr);
100
101 if (!r->resolve_name("127.0.0.1", (struct sockaddr **)&s, &slen)) {
102 printf("A second try to resolve failed after first success, cache broken\n");
103 } else {
104 printf("Successfully resolved to 0x%x again\n", s->sin_addr.s_addr);
105 }
106
107 std::string name;
108 if (!r->resolve_address((struct sockaddr *)s, slen, name)) {
109 // printf("Resolving address failed\n");
110 } else {
111 printf("Successfully resolved address to '%s'\n", name.c_str());
112 }
113
114 const char *atmp;
115 if ((atmp = argp->arg("h")) != NULL) {
116 printf("Trying to resolve %s\n", atmp);
117 while (!quit && !r->resolve_name(atmp, (struct sockaddr **)&s, &slen)) {
118 usleep(0);
119 }
120 if (quit) {
121 return;
122 }
123 char addrp[INET_ADDRSTRLEN];
124 inet_ntop(AF_INET, &(s->sin_addr), addrp, sizeof(addrp));
125 printf("Successfully resolved to 0x%x (%s)\n", s->sin_addr.s_addr, addrp);
126
127 struct sockaddr_in so;
128 std::string tmp;
129 slen = sizeof(so);
130 so.sin_addr.s_addr = s->sin_addr.s_addr;
131 r->resolve_address((struct sockaddr *)&so, slen, tmp);
132 printf("Waiting one second to allow resolver thread to suceed\n");
133 sleep(1);
134 if (r->resolve_address((struct sockaddr *)&so, slen, tmp)) {
135 printf("Successfully resolved 0x%x to %s\n", so.sin_addr.s_addr, tmp.c_str());
136 }
137 }
138
139 if ((atmp = argp->arg("i")) != NULL) {
140 printf("Resolving %s, press Ctrl-C to end...\n", atmp);
141 struct in_addr ia;
142 if (inet_pton(AF_INET, atmp, &ia) == 1) {
143 while (!quit) {
144 struct sockaddr_in so;
145 so.sin_addr.s_addr = ia.s_addr;
146 std::string name;
147 if (r->resolve_address((struct sockaddr *)&so, sizeof(so), name)) {
148 //printf("Successfully resolved to %s\n", name);
149 //if (name != "zadeat-1.local") {
150 // printf("Unexpected results: %s\n", name.c_str());
151 //}
152 printf("Result: %s\n", name.c_str());
153 }
154 usleep(50000);
155 }
156 } else {
157 printf("Address could not be converted to binary form. Skipping.\n");
158 }
159 }
160 }
161
162 virtual void
163 handle_signal(int signum)
164 {
165 quit = true;
166 }
167
168private:
169 ArgumentParser * argp;
171 bool quit;
172#ifdef HAVE_AVAHI
173 AvahiThread *at;
174#endif
175};
176
177int
178main(int argc, char **argv)
179{
180 ArgumentParser argp(argc, argv, "ah:i:");
181
182 ResolverQAMain m(&argp);
183 SignalManager::register_handler(SIGINT, &m);
184 SignalManager::ignore(SIGPIPE);
185
186 m.run();
187
188 SignalManager::finalize();
189
190 return 0;
191}
192
193/// @endcond
Parse command line arguments.
Definition: argparser.h:64
const char * arg(const char *argn)
Get argument value.
Definition: argparser.cpp:177
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:165
Avahi main thread.
Definition: avahi_thread.h:55
Network name and address resolver.
Definition: resolver.h:45
Interface for signal handling.
Definition: signal.h:36
Fawkes library namespace.