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

version» Context lines:

pike.git/lib/modules/Protocols.pmod/DNS.pmod:205:    m->ar=decode_entries(s,m->arcount,next);    return m;    }   };         class client {    inherit protocol;       string nameserver; -  +  array search = ({});    void create(void|string server)    {    if(!server)    { -  +  string domain;    foreach(Stdio.read_file("/etc/resolv.conf")/"\n", string line)    {    string rest;    sscanf(line,"%s#",line);    sscanf(line,"%*[\r \t]%s",line);    line=reverse(line);    sscanf(line,"%*[\r \t]%s",line);    line=reverse(line);    sscanf(line,"%s%*[ \t]%s",line,rest);    switch(line)    {    case "domain": -  +  // Save domain for later. +  domain = rest; +  break;    case "search": -  break; // Not yet implemented +  rest = replace(rest, "\t", " "); +  foreach(rest / " " - ({""}), string dom) +  search += ({dom}); +  break;       case "nameserver":    nameserver=rest;    break;    }    } -  }else{ +  if(domain) +  search = ({ domain }) + search; +  } else {    nameserver=server;    }    }          // Warning: NO TIMEOUT    mapping do_sync_query(string s)    {    object udp=spider.dumUDP();    udp->bind(0);
pike.git/lib/modules/Protocols.pmod/DNS.pmod:255:    } while (m->port != 53 ||    m->ip != nameserver ||    m->data[0..1]!=s[0..1]);    return decode_res(m->data);    }          // Warning: NO TIMEOUT    mixed *gethostbyname(string s)    { -  mapping m=do_sync_query(mkquery(s, C_IN, T_A)); +  mapping m; +  if(sizeof(search) && s[-1] != '.' && sizeof(s/".") < 3) { +  m=do_sync_query(mkquery(s, C_IN, T_A)); +  if(!m || !m->an || !sizeof(m->an)) +  foreach(search, string domain) +  { +  m=do_sync_query(mkquery(s+"."+domain, C_IN, T_A)); +  if(m && m->an && sizeof(m->an)) +  break; +  } +  } else { +  m=do_sync_query(mkquery(s, C_IN, T_A)); +  } +     string *names=({});    string *ips=({});    foreach(m->an, mapping x)    {    if(x->name)    names+=({x->name});    if(x->a)    ips+=({x->a});    }    return ({
pike.git/lib/modules/Protocols.pmod/DNS.pmod:307:    }    return ({    sizeof(names)?names[0]:0,    ips,    names,    });    }       string get_primary_mx(string host)    { -  mapping m=do_sync_query(mkquery(host,C_IN,T_MX)); +  mapping m; +  if(sizeof(search) && host[-1] != '.' && sizeof(host/".") < 3) { +  m=do_sync_query(mkquery(host, C_IN, T_MX)); +  if(!m || !m->an || !sizeof(m->an)) +  foreach(search, string domain) +  { +  m=do_sync_query(mkquery(host+"."+domain, C_IN, T_MX)); +  if(m && m->an && sizeof(m->an)) +  break; +  } +  } else { +  m=do_sync_query(mkquery(host, C_IN, T_MX)); +  }    int minpref=29372974;    string ret;    foreach(m->an, mapping m2)    {    if(m2->preference<minpref)    {    ret=m2->mx;    minpref=m2->preference;    }    }
pike.git/lib/modules/Protocols.pmod/DNS.pmod:372:    void do_query(string domain, int cl, int type,    function(string,mapping,mixed...:void) callback,    mixed ... args)    {    id++;    id&=65535;    string req=low_mkquery(id,domain,cl,type);       if(requests[id])    throw(({"Cannot find an empty request slot.\n",backtrace()})); -  +     object r=Request();    r->req=req;    r->domain=domain;    r->callback=callback;    r->args=args;    requests[id]=r;    call_out(retry,5,r);    udp::send(nameserver,53,r->req);    }   
pike.git/lib/modules/Protocols.pmod/DNS.pmod:397:    sscanf(m->data,"%2c",int id);    object r=requests[id];    if(!r) return;    m_delete(requests,id);    r->callback(r->domain,decode_res(m->data),@r->args);    destruct(r);    }       static private void generic_get(string d,    mapping answer, +  int multi,    string field,    string domain,    function callback,    mixed ... args)    {    if(!answer || !answer->an || !sizeof(answer->an))    { -  +  if(multi == -1 || sizeof(search) < multi) { +  // Either a request without multi (ip, or FQDN) or we have tried all +  // domains.    callback(domain,0,@args); -  }else{ +  } else { +  // Multiple domain request. Try the next one... +  do_query(domain+"."+search[multi], C_IN, T_A, +  generic_get, ++multi, "a", domain, callback, @args); +  } +  } else {    foreach(answer->an, array an)    if(an[field])    {    callback(domain,an[field],@args);    return;    }    callback(domain,0,@args);    return;    }    }       void host_to_ip(string host, function callback, mixed ... args)    { -  +  if(sizeof(search) && host[-1] != '.' && sizeof(host/".") < 3) {    do_query(host, C_IN, T_A, -  generic_get,"a", -  host, callback, -  @args ); +  generic_get, 0, "a", host, callback, @args ); +  } else { +  do_query(host, C_IN, T_A, +  generic_get, -1, "a", +  host, callback, @args);    } -  +  }       void ip_to_host(string ip, function callback, mixed ... args)    {    do_query(arpa_from_ip(ip), C_IN, T_PTR, -  generic_get, "ptr", +  generic_get, -1, "ptr",    ip, callback,    @args);    }       void create(void|string server)    {    if(!udp::bind(0))    throw(({"DNS: failed to bind a port.\n",backtrace()}));       udp::set_read_callback(rec_data);    ::create(server);    }   };