Fawkes API Fawkes Development Version

qa_resolver.cpp

00001 
00002 /***************************************************************************
00003  *  qa_resolver.cpp - Fawkes QA for resolver
00004  *
00005  *  Created: Thu May 10 19:10:03 2007
00006  *  Copyright  2006-2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 /// @cond QA
00025 
00026 #include <netcomm/utils/resolver.h>
00027 #include <utils/system/signal.h>
00028 #include <utils/system/argparser.h>
00029 #ifdef HAVE_AVAHI
00030 #include <netcomm/dns-sd/avahi_thread.h>
00031 #endif
00032 
00033 #include <netinet/in.h>
00034 #include <arpa/inet.h>
00035 #include <cstdio>
00036 #include <cstdlib>
00037 #include <cstring>
00038 
00039 using namespace fawkes;
00040 
00041 class ResolverQAMain : public SignalHandler
00042 {
00043  public:
00044   ResolverQAMain(ArgumentParser *argp)
00045   {
00046     this->argp = argp;
00047     quit = false;
00048 
00049     r = NULL;
00050 
00051 #ifdef HAVE_AVAHI
00052     at = NULL;
00053     if ( argp->has_arg("a") ) {
00054       printf("Instantiating Avahi thread\n");
00055       at = new AvahiThread();
00056       at->start();
00057       at->wait_initialized();
00058       usleep(0);
00059     }
00060     r = new NetworkNameResolver(at);
00061 #else
00062     if ( argp->has_arg("a") ) {
00063       printf("Avahi not available at compile time\n");
00064     }
00065     r = new NetworkNameResolver();
00066 #endif
00067 
00068   }
00069 
00070   ~ResolverQAMain()
00071   {
00072 #ifdef HAVE_AVAHI
00073     if ( at != NULL ) {
00074       at->cancel();
00075       at->join();
00076       delete at;
00077     }
00078 #endif
00079     delete r;
00080   }
00081 
00082   void run()
00083   {
00084     struct sockaddr_in *s = NULL;
00085     socklen_t slen;
00086 
00087     char *test = (char *)malloc(strlen("127.0.0.1") + 1);
00088     strcpy(test, "127.0.0.1");
00089     r->resolve_name(test, (struct sockaddr **)&s, &slen);
00090     free(test);
00091 
00092     while ( ! quit && ! r->resolve_name("127.0.0.1", (struct sockaddr **)&s, &slen) ) {
00093       usleep(0);
00094     }
00095     if ( quit ) {
00096       return;
00097     }
00098     printf("Successfully resolved to 0x%x\n", s->sin_addr.s_addr);
00099   
00100     if ( ! r->resolve_name("127.0.0.1", (struct sockaddr **)&s, &slen) ) {
00101       printf("A second try to resolve failed after first success, cache broken\n");
00102     } else {
00103       printf("Successfully resolved to 0x%x again\n", s->sin_addr.s_addr);
00104     }
00105 
00106     std::string name;
00107     if ( ! r->resolve_address((struct sockaddr *)s, slen, name) ) {
00108       // printf("Resolving address failed\n");
00109     } else {
00110       printf("Successfully resolved address to '%s'\n", name.c_str());
00111     }
00112 
00113     const char *atmp;
00114     if ( (atmp = argp->arg("h")) != NULL ) {
00115       printf("Trying to resolve %s\n", atmp);
00116       while ( ! quit && ! r->resolve_name(atmp, (struct sockaddr **)&s, &slen) ) {
00117         usleep(0);
00118       }
00119       if ( quit ) {
00120         return;
00121       }
00122       char addrp[INET_ADDRSTRLEN];
00123       inet_ntop(AF_INET, &(s->sin_addr), addrp, sizeof(addrp));
00124       printf("Successfully resolved to 0x%x (%s)\n", s->sin_addr.s_addr, addrp);
00125 
00126       struct sockaddr_in so;
00127       std::string tmp;
00128       slen = sizeof(so);
00129       so.sin_addr.s_addr = s->sin_addr.s_addr;
00130       r->resolve_address((struct sockaddr *)&so, slen, tmp);
00131       printf("Waiting one second to allow resolver thread to suceed\n");
00132       sleep(1);
00133       if ( r->resolve_address((struct sockaddr *)&so, slen, tmp) ) {
00134         printf("Successfully resolved 0x%x to %s\n", so.sin_addr.s_addr, tmp.c_str());
00135       } 
00136     }
00137 
00138     if ( (atmp = argp->arg("i")) != NULL ) {
00139       printf("Resolving %s, press Ctrl-C to end...\n", atmp);
00140       struct in_addr ia;
00141       if (inet_pton(AF_INET, atmp, &ia) == 1) {
00142         while ( ! quit) {
00143           struct sockaddr_in so;
00144           so.sin_addr.s_addr = ia.s_addr;
00145           std::string name;
00146           if ( r->resolve_address((struct sockaddr *)&so, sizeof(so), name) ) {
00147             //printf("Successfully resolved to %s\n", name);
00148             //if (name != "zadeat-1.local") {
00149             //  printf("Unexpected results: %s\n", name.c_str());
00150             //}
00151             printf("Result: %s\n", name.c_str());
00152           }
00153           usleep(50000);
00154         }
00155       } else {
00156         printf("Address could not be converted to binary form. Skipping.\n");
00157       }
00158     }
00159   }
00160 
00161   virtual void handle_signal(int signum)
00162   {
00163     quit = true;
00164   }
00165 
00166  private:
00167   ArgumentParser *argp;
00168   NetworkNameResolver *r;
00169   bool quit;
00170 #ifdef HAVE_AVAHI
00171   AvahiThread *at;
00172 #endif
00173 };
00174 
00175 int
00176 main(int argc, char **argv)
00177 {
00178   ArgumentParser argp(argc, argv, "ah:i:");
00179 
00180   ResolverQAMain m(&argp);
00181   SignalManager::register_handler(SIGINT, &m);
00182   SignalManager::ignore(SIGPIPE);
00183 
00184   m.run();
00185 
00186   SignalManager::finalize();
00187 
00188   return 0;
00189 }
00190 
00191 
00192 /// @endcond
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends