Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

My attempt with Ruby and Celluloid.

https://gist.github.com/a803d86234e8d1fc5496

I also include a list of 100 domains in a domains.txt if anyone wants to try for themselves.

    require "socket"
    require "celluloid"

    class IPGetter
      include Celluloid

      def get(url)
        Socket.getaddrinfo(url, "http")[0][2]
      end
    end

    pool = IPGetter.pool(size: 100)
    ips = {}

    File.open("domains.txt").each_line do |line|
      line.chomp!
      ips[line] = pool.future.get(line)
    end

    ips.each do |url, ip_future|
      puts "#{url} => #{ip_future.value}"
    end


In Scala using the par function: https://gist.github.com/4199415

    def ip(host:String)=java.net.InetAddress.getAllByName(host)(0).getHostAddress
    var map = Map[String,String]()
    val hosts = List("google.com","twitter.com","facebook.com")
    hosts.par.map(host => (host,ip(host))).foreach(hostip => map+=(hostip._1->hostip._2))

    scala> map
    res1: scala.collection.immutable.Map[String,String]
     =Map(google.com -> 74.125.224.71,
          twitter.com -> 199.59.150.7, 
          facebook.com -> 69.171.229.16)


Or Erlang

https://gist.github.com/bb01a85404e6b445dcb3#file_resolve_do...

    % -*- erlang -*-                                                                                                                              
    %%! -smp enable                                                                                                                               
                                                                                                                                                  
    worker(Hostname) ->                                                                                                                           
        {ok, IP} = inet:getaddr(Hostname, inet),                                                                                                  
        io:format(                                                                                                                                
          "~s => ~s~n",                                                                                                                                 
          [ip_to_string(IP)]                                                                                                                      
         ).                                                                                                                                       
                                                                                                                                                  
    ip_to_string({N1,N2,N3,N4}) ->                                                                                                                
        io_lib:format(                                                                                                                            
          "~w.~w.~w.~w",                                                                                                                          
          [N1,N2,N3,N4]                                                                                                                           
         ).                                                                                                                                       
                                                                                                                                                  
    main([DomainFile]) ->                                                                                                                         
        {ok, Bin} = file:read_file(DomainFile),                                                                                                   
        String = binary_to_list(Bin),                                                                                                             
        Domains = string:tokens(String, "\n"),                                                                                                    
        plists:foreach(                                                                                                                           
          fun(Domain) -> worker(Domain) end,                                                                                                      
          Domains                                                                                                                                 
        ).

This uses https://github.com/eveel/plists/


How about a few lines of C?

  // clang -lcares -I/opt/local/include -L/opt/local/lib -o domains domains.c
  #include <ares.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <sys/socket.h>
  #include <arpa/inet.h>
  #include <netinet/in.h>
  #include <netdb.h>
  #include <stdarg.h>
  #include <string.h>
  #include <ctype.h>
  #include <unistd.h>
  #include <sys/queue.h>
  #include <fcntl.h>
  
  static void callback(void *arg, int status, int timeouts, struct hostent *host)
  {
  
      if(!host || status != ARES_SUCCESS){
          printf("Failed to lookup %s\n", ares_strerror(status));
          return;
      }
  
      char ip[INET6_ADDRSTRLEN];
      int i = 0;
  
      for (i = 0; host->h_addr_list[i]; ++i) {
          inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
          printf("%s: %s\n", host->h_name, ip);
      }
  }
  
  static void wait_ares(ares_channel channel)
  {
      for(;;){
          struct timeval *tvp, tv;
          fd_set read_fds, write_fds;
          int nfds;
  
          FD_ZERO(&read_fds);
          FD_ZERO(&write_fds);
          nfds = ares_fds(channel, &read_fds, &write_fds);
          if(nfds == 0){
              break;
          }
          tvp = ares_timeout(channel, NULL, &tv);
          select(nfds, &read_fds, &write_fds, NULL, tvp);
          ares_process(channel, &read_fds, &write_fds);
      }
  }
  
  struct Request {
      ares_channel channel;
      char* domain;
      SLIST_ENTRY(Request) next;
  };
  
  int main(const int argc, const char* argv[]) {
      SLIST_HEAD(Requests, Request) requests;
      SLIST_INIT(&requests);
      struct Request* last = NULL;
  
      int status;
      struct ares_options options;
      int optmask = 0;
      const char* path;
  
      optmask |= ARES_OPT_TIMEOUTMS;
      options.timeout = 1000;
  
      status = ares_library_init(ARES_LIB_INIT_ALL);
      if (status != ARES_SUCCESS){
          printf("ares_library_init: %s\n", ares_strerror(status));
          return 1;
      }
  
      for (int i = 1; (path = argv[i]) != NULL || i == 0; i++) {
          
          int fd = open(path, O_RDONLY);
          FILE* fp = fdopen(fd, "r");
          char* buffer = NULL;
          size_t bufferSize = 0;
          int lineLength = 0;
          
          while ((lineLength = getline(&buffer, &bufferSize, fp)) > 0) {
  
              struct Request* request = malloc(sizeof(struct Request));
  
              status = ares_init_options(&request->channel, &options, optmask);
              if(status != ARES_SUCCESS) {
                  printf("ares_init_options: %s\n", ares_strerror(status));
                  continue;
              }
              
              buffer[lineLength - 1] = '\0';
  
              request->domain = buffer;
              buffer = NULL;
              if (NULL == last) {
                  SLIST_INSERT_HEAD(&requests, request, next);
              } else {
                  SLIST_INSERT_AFTER(last, request, next);
              }
              last = request;
  
              ares_gethostbyname(request->channel, request->domain, AF_INET, callback, NULL);
          }
      }
  
      while (!SLIST_EMPTY(&requests)) {
          struct Request* request = SLIST_FIRST(&requests);
          wait_ares(request->channel);
          ares_destroy(request->channel);
          free(request->domain);
          SLIST_REMOVE_HEAD(&requests, next);
          free(request);
      }
  
      ares_library_cleanup();
      return 0;
  }




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: