pike.git/lib/modules/Protocols.pmod/DNS.pmod:657:
// Try IPv6 any (::) too for paranoia reasons.
// For even more paranoia, try sending some data
// from :: to the drain services on 127.0.0.1 and ::1.
//
// If the tests fail, we regard the IPv6 support as broken,
// and use just IPv4.
Stdio.UDP udp = Stdio.UDP();
if (udp->bind(0, "::1") && udp->bind(0, "::") &&
(udp->send("127.0.0.1", 9, "/dev/null") == 9) &&
(udp->send("::1", 9, "/dev/null") == 9)) {
+ // Note: The above tests are apparently not sufficient, since
+ // WIN32 happily pretends to send stuff to ::ffff:0:0/96...
+ Stdio.UDP udp2 = Stdio.UDP();
+ if (udp2->bind(0, "127.0.0.1")) {
+ // IPv4 is present.
+ array(string) a = udp2->query_address()/" ";
+ int port = (int)a[1];
+ string key = Crypto.Random.random_string(16);
+ udp2->set_nonblocking();
+
+ // We shouldn't get any lost packets, since we're on the loop-back,
+ // but for paranoia reasons we perform a couple of retries.
+ retry:
+ for (int i = 0; i < 16; i++) {
+ if (!udp->send("127.0.0.1", port, key)) continue;
+ // udp2->wait() throws errors on WIN32.
+ catch(udp2->wait(1));
+ mapping res;
+ while ((res = udp2->read())) {
+ if (res->data == key) {
+ // Mapped IPv4 seems to work.
ANY = "::";
-
+ break retry;
}
-
+ }
+ }
+ destruct(udp2);
+ }
+ }
destruct(udp);
};
}
//! Base class for implementing a Domain Name Service (DNS) server.
//!
//! This class is typically used by inheriting it,
//! and overloading @[reply_query()] and @[handle_response()].
class server
{
pike.git/lib/modules/Protocols.pmod/DNS.pmod:852:
class client
{
inherit protocol;
#ifdef __NT__
array(string) get_tcpip_param(string val, void|string fallbackvalue)
{
array(string) res = ({});
foreach(({
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+ "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters",
"SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP"
}),string key)
{
catch {
res += ({ RegGetValue(HKEY_LOCAL_MACHINE, key, val) });
};
}
#if constant(RegGetKeyNames)
/* Catch if RegGetKeyNames() doesn't find the directory. */
pike.git/lib/modules/Protocols.pmod/DNS.pmod:873: Inside #if defined(__NT__) and #if constant(RegGetKeyNames)
foreach(RegGetKeyNames(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\"
"Parameters\\Interfaces"), string key)
{
catch {
res += ({ RegGetValue(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\"
"Parameters\\Interfaces\\" + key, val) });
};
}
+ foreach(RegGetKeyNames(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\"
+ "Parameters\\Interfaces"), string key)
+ {
+ catch {
+ res += ({ RegGetValue(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\"
+ "Parameters\\Interfaces\\" + key, val) });
};
-
+ }
+ };
#endif
res -= ({ UNDEFINED });
return sizeof(res) ? res : ({ fallbackvalue });
}
#else /* !__NT__ */
protected private mapping(string:string) etc_hosts;
protected private int is_ip(string ip)
pike.git/lib/modules/Protocols.pmod/DNS.pmod:1113: Inside #if 0
#if 0
werror("Protocols.DNS.client()->do_sync_query(%O)\n"
"UDP Address: %s\n"
"%s\n", s, udp->query_address(), describe_backtrace(backtrace()));
#endif /* 0 */
mapping m;
for (i=0; i < RETRIES; i++) {
udp->send(nameservers[i % sizeof(nameservers)], 53, s);
// upd->wait() can throw an error sometimes.
- catch
- {
- while (udp->wait(RETRY_DELAY))
- {
+ //
+ // One common case is on WIN32 where select complains
+ // about it not being a socket.
+ catch {
+ udp->wait(RETRY_DELAY);
+ };
+ // Make sure that udp->read() doesn't block.
+ udp->set_nonblocking();
// udp->read() can throw an error on connection refused.
catch {
m = udp->read();
- if ((m->port == 53) &&
+ if (m && (m->port == 53) &&
(m->data[0..1] == s[0..1]) &&
has_value(nameservers, m->ip)) {
// Success.
return decode_res(m->data);
}
};
-
+ // Restore blocking state for udp->send() on retry.
+ udp->set_blocking();
}
- };
- }
+
// Failure.
return 0;
}
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))