pike.git/lib/modules/Protocols.pmod/DNS.pmod:1:
- // $Id: DNS.pmod,v 1.95 2008/03/10 13:41:11 grubba Exp $
+ // $Id: DNS.pmod,v 1.96 2008/06/28 16:36:56 nilsson Exp $
// Not yet finished -- Fredrik Hubinette
//! Domain Name System
//! RFC 1035
#pike __REAL_VERSION__
constant NOERROR=0;
constant FORMERR=1;
constant SERVFAIL=2;
pike.git/lib/modules/Protocols.pmod/DNS.pmod:104:
//! Low level DNS protocol
class protocol
{
string mklabel(string s)
{
if(sizeof(s)>63)
error("Too long component in domain name.\n");
return sprintf("%c%s",sizeof(s),s);
}
- static private string mkname(string|array(string) labels, int pos,
+ protected private string mkname(string|array(string) labels, int pos,
mapping(string:int) comp)
{
if(stringp(labels))
labels = labels/"."-({""});
if(!labels || !sizeof(labels))
return "\0";
string n = labels*".";
if(comp[n])
return sprintf("%2c", comp[n]|0xc000);
else {
if(pos<0x4000)
comp[n]=pos;
string l = mklabel(labels[0]);
return l + mkname(labels[1..], pos+sizeof(l), comp);
}
}
- static string make_raw_addr6(string addr6)
+ protected string make_raw_addr6(string addr6)
{
if(!addr6) return "\0"*16;
if(has_value(addr6, "::")) {
int parts = sizeof((addr6/":")-({""}));
if(has_value(addr6, ".")) parts++;
addr6 = replace(addr6, "::", ":"+"0:"*(8-parts));
sscanf(addr6, ":%s", addr6);
}
if(has_value(addr6, "."))
return sprintf("%2c%2c%2c%2c%2c%2c%1c%1c%1c%1c",
@array_sscanf(addr6, "%x:%x:%x:%x:%x:%x:%x.%x.%x.%x"));
else
return sprintf("%@2c",
array_sscanf(addr6, "%x:%x:%x:%x:%x:%x:%x:%x"));
}
- static private string mkrdata(mapping entry, int pos, mapping(string:int) c)
+ protected private string mkrdata(mapping entry, int pos, mapping(string:int) c)
{
switch(entry->type) {
case T_CNAME:
return mkname(entry->cname, pos, c);
case T_PTR:
return mkname(entry->ptr, pos, c);
case T_NS:
return mkname(entry->ns, pos, c);
case T_MD:
return mkname(entry->md, pos, c);
pike.git/lib/modules/Protocols.pmod/DNS.pmod:199:
lambda(string t) {
return sprintf("%1c%s", sizeof(t), t);
})*"";
case T_LOC:
// FIXME: Not implemented yet.
default:
return "";
}
}
- static private string encode_entries(array(mapping) entries, int pos,
+ protected private string encode_entries(array(mapping) entries, int pos,
mapping(string:int) comp)
{
string res="";
foreach(entries, mapping entry) {
string e = mkname(entry->name, pos, comp)+
sprintf("%2c%2c%4c", entry->type, entry->cl, entry->ttl);
pos += sizeof(e)+2;
string rd = entry->rdata || mkrdata(entry, pos, comp);
res += e + sprintf("%2c", sizeof(rd)) + rd;
pos += sizeof(rd);
pike.git/lib/modules/Protocols.pmod/DNS.pmod:488:
return m;
}
};
//! Implements a Domain Name Service (DNS) server.
class server
{
inherit protocol;
inherit Stdio.UDP : udp;
- static void send_reply(mapping r, mapping q, mapping m)
+ protected void send_reply(mapping r, mapping q, mapping m)
{
// FIXME: Needs to handle truncation somehow.
if(!r)
r = (["rcode":4]);
r->id = q->id;
r->qr = 1;
r->opcode = q->opcode;
r->rd = q->rd;
r->qd = r->qd || q->qd;
string s = mkquery(r);
pike.git/lib/modules/Protocols.pmod/DNS.pmod:529:
//! @mapping
//! @member string|array(string) "name"
//! @member int "type"
//! @member int "cl"
//! @endmapping
//! @endarray
//! @member array|void "an"
//! @member array|void "ns"
//! @member array|void "ar"
//! @endmapping
- static mapping reply_query(mapping query, mapping udp_data)
+ protected mapping reply_query(mapping query, mapping udp_data)
{
// Override this function.
//
// Return mapping may contain:
// aa, ra, {ad, cd,} rcode, an, ns, ar
return 0;
}
- static void handle_query(mapping q, mapping m)
+ protected void handle_query(mapping q, mapping m)
{
mapping r = reply_query(q, m);
send_reply(r, q, m);
}
- static void handle_response(mapping r, mapping m)
+ protected void handle_response(mapping r, mapping m)
{
// This is a stub intended to simplify servers which allow recursion
}
- static private void rec_data(mapping m)
+ protected private void rec_data(mapping m)
{
mixed err;
mapping q;
if (err = catch {
q=decode_res(m->data);
}) {
werror("DNS: Failed to read UDP packet.\n%s\n",
describe_backtrace(err));
if(m && m->data && sizeof(m->data)>=2)
send_reply((["rcode":1]),
pike.git/lib/modules/Protocols.pmod/DNS.pmod:629: Inside #if defined(__NT__) and #if constant(RegGetKeyNames)
"Parameters\\Interfaces\\" + key, val) });
};
}
};
#endif
return sizeof(res) ? res : ({ fallbackvalue });
}
#else /* !__NT__ */
- static private mapping(string:string) etc_hosts;
+ protected private mapping(string:string) etc_hosts;
- static private int is_ip(string ip)
+ protected private int is_ip(string ip)
{
// FIXME: Doesn't work with IPv6
return (replace(ip, "0123456789."/1, allocate(11,"")) == "");
}
- static private string read_etc_file(string fname)
+ protected private string read_etc_file(string fname)
{
array(string) paths;
string res;
#ifdef __NT__
paths = get_tcpip_param("DataBasePath");
#else
paths = ({ "/etc", "/amitcp/db" });
#endif
foreach(paths, string path) {
string raw = Stdio.read_file(path + "/" + fname);
pike.git/lib/modules/Protocols.pmod/DNS.pmod:663:
}
res += raw;
} else {
res = raw;
}
}
}
return res;
}
- static private string match_etc_hosts(string host)
+ protected private string match_etc_hosts(string host)
{
if (!etc_hosts) {
etc_hosts = ([ "localhost":"127.0.0.1" ]);
string raw = read_etc_file("hosts");
if (raw && sizeof(raw)) {
foreach(raw/"\n"-({""}), string line) {
// Handle comments, and split the line on white-space
line = lower_case(replace((line/"#")[0], "\t", " "));
pike.git/lib/modules/Protocols.pmod/DNS.pmod:877:
return decode_res(m->data);
}
};
}
};
}
// Failure.
return 0;
}
- static mapping low_gethostbyname(string s, int type)
+ protected mapping low_gethostbyname(string s, int type)
{
mapping m;
if(sizeof(domains) && s[-1] != '.' && sizeof(s/".") < 3) {
mapping m = do_sync_query(mkquery(s, C_IN, type));
if(!m || !m->an || !sizeof(m->an))
foreach(domains, string domain)
{
m = do_sync_query(mkquery(s+"."+domain, C_IN, type));
if(m && m->an && sizeof(m->an))
break;
pike.git/lib/modules/Protocols.pmod/DNS.pmod:1180:
string req;
string domain;
function callback;
int retries;
int timestamp;
array args;
};
mapping requests=([]);
- static private void remove(object(Request) r)
+ protected 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)
{
pike.git/lib/modules/Protocols.pmod/DNS.pmod:1240:
/* 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->do_query(domain, cl, type, callback, @args);
}
- static private void rec_data(mapping m)
+ protected private void rec_data(mapping m)
{
mixed err;
if (err = catch {
if(m->port != 53 || !has_value(nameservers, m->ip)) return;
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);
}) {
werror("DNS: Failed to read UDP packet. Connection refused?\n%s\n",
describe_backtrace(err));
}
}
- static private void generic_get(string d,
+ protected private void generic_get(string d,
mapping answer,
int multi,
int all,
int type,
string field,
string domain,
function callback,
mixed ... args)
{
if(!answer || !answer->an || !sizeof(answer->an))