pike.git / lib / modules / Protocols.pmod / DNS.pmod

version» Context lines:

pike.git/lib/modules/Protocols.pmod/DNS.pmod:266:    }    } else {    // Couldn't read /etc/hosts.    }    }    return(etc_hosts[lower_case(host)]);    }       array(string) nameservers = ({});    array domains = ({}); -  void create(void|string server) +  void create(void|string|array(string) server, void|int|array(string) domain)    {    if(!server)    {    string domain;   #if __NT__          domain=get_tcpip_param("Domain");    nameservers = ({ get_tcpip_param("NameServer") });    domains=get_tcpip_param("SearchList") / " "- ({""});
pike.git/lib/modules/Protocols.pmod/DNS.pmod:335:    }    if(domain)    domains = ({ domain }) + domains;    domains = Array.map(domains, lambda(string d) {    if (d[-1] == '.') {    return d[..sizeof(d)-2];    }    return d;    });    } else { +  if(arrayp(server)) +  nameservers= server; +  else    nameservers= ({ server }); -  +  +  if(arrayp(domain)) +  domains = domain; +  else +  domains = ({ domains }); +     }    }          // Warning: NO TIMEOUT    mapping do_sync_query(string s)    {    object udp=spider.dumUDP();    udp->bind(0);    udp->send(nameservers[0],53,s);
pike.git/lib/modules/Protocols.pmod/DNS.pmod:451:    if(m2->preference<minpref)    {    ret=m2->mx;    minpref=m2->preference;    }    }    return ret;    }   }    + #define RETRIES 12 + #define RETRY_DELAY 5 + #define REMOVE_DELAY 120 + #define GIVE_UP_DELAY (RETRIES * RETRY_DELAY + REMOVE_DELAY)*2      class async_client   {    inherit client;    inherit spider.dumUDP : udp;    int id; -  +  async_client next_client;      #if constant(thread_create) -  object lock = Thread.Mutex(); +  static private inherit Thread.Mutex : lock;   #endif /* constant(thread_create) */       class Request    {    string req;    string domain;    function callback;    int retries; -  +  int timestamp;    mixed *args;    };       mapping requests=([]);    -  +     static private void remove(object(Request) r)    {    if(!r) return;    sscanf(r->req,"%2c",int id);    m_delete(requests,id);    r->callback(r->domain,0,@r->args);    destruct(r);    }       void retry(object(Request) r, void|int nsno)    {    if(!r) return;    if (nsno >= sizeof(nameservers)) { -  if(r->retries++ > 12) +  if(r->retries++ > RETRIES)    { -  call_out(remove,120,r); +  call_out(remove,REMOVE_DELAY,r);    return;    } else {    nsno = 0;    }    }       send(nameservers[nsno],53,r->req); -  call_out(retry,5,r,nsno+1); +  call_out(retry,RETRY_DELAY,r,nsno+1);    }       void do_query(string domain, int cl, int type,    function(string,mapping,mixed...:void) callback,    mixed ... args)    { -  +  int lid;   #if constant(thread_create) -  object key = lock->lock(); +  object key=lock::lock();   #endif /* constant(thread_create) */ -  +  for(int e=next_client ? 5 : 1024;e>=0;e--) +  {    id++;    id&=65535; -  int lid = id; +  lid=id;    -  +  if(requests[lid]) +  { +  if(time() - requests[lid]->timestamp > GIVE_UP_DELAY) +  {   #if constant(thread_create) -  key = 0; +  // We need to unlock the lock for the remove operation... +  key=0;   #endif /* constant(thread_create) */ -  +  remove(requests[lid]); + #if constant(thread_create) +  key=lock::lock(); + #endif /* constant(thread_create) */ +  if(requests[lid]) continue; +  }else{ +  continue; +  } +  } +  break; +  }       if(requests[lid]) -  throw(({"Cannot find an empty request slot.\n",backtrace()})); +  { +  /* We failed miserably to find a request id to use, +  * so we create a second UDP port to be able to have more +  * requests 'in the air'. /Hubbe +  */ +  if(!next_client) +  { +  next_client=async_client(nameservers,domains); +  next_client->nameservers=nameservers; +  next_client->domains=domains; +  }    -  + #if constant(thread_create) +  key=0; + #endif /* constant(thread_create) */ +  +  next_client->do_query(domain, cl, type, callback, @args); +  return; +  } +     string req=low_mkquery(lid,domain,cl,type);       object r=Request();    r->req=req;    r->domain=domain;    r->callback=callback;    r->args=args; -  +  r->timestamp=time();    requests[lid]=r;    udp::send(nameservers[0],53,r->req); -  call_out(retry,5,r,1); +  call_out(retry,RETRY_DELAY,r,1);    }       static private void rec_data()    {    mixed err;    if (err = catch {    mapping m=udp::read();    if(m->port != 53 || search(nameservers, m->ip) == -1) return;    sscanf(m->data,"%2c",int id);    object r=requests[id];
pike.git/lib/modules/Protocols.pmod/DNS.pmod:600:    }       void ip_to_host(string ip, function callback, mixed ... args)    {    do_query(arpa_from_ip(ip), C_IN, T_PTR,    generic_get, -1, "ptr",    ip, callback,    @args);    }    -  void create(void|string server) +  void create(void|string|array(string) server, void|string|array(string) domain)    {    if(!udp::bind(0))    throw(({"DNS: failed to bind a port.\n",backtrace()}));       udp::set_read_callback(rec_data); -  ::create(server); +  ::create(server,domain);    }   };