pike.git
/
lib
/
modules
/
Protocols.pmod
/
DNS.pmod
version
»
Context lines:
10
20
40
80
file
none
3
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); } };