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: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
);
} };