new object $dns: $network;
var $dmi_data descriptions = #[];
var $dns async = 0;
var $dns connection = 0;
var $dns dnshost = ["127.0.0.1", 1153];
var $dns started = 0;
var $dns starting = 0;
var $dns valid_host_regexp = "^([-a-z0-9]+\.)+(gov|edu|com|org|int|mil|net|nato|arpa|[a-z][a-z])$";
var $dns valid_ip_regexp = "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)";
var $root created_on = 867779129;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root inited = 1;
var $root managed = [$dns];
var $root manager = $dns;
var $root trusted_by = [$outbound_connection];
public method .connection_going_away() {
arg host, port;
if (sender() != connection)
return;
started = 0;
if (!starting)
.restart();
};
public method .connection_starting() {
arg host, port;
};
public method .core_dns() {
async = 0;
connection = 0;
starting = 0;
started = 0;
};
public method .hostname() {
arg ip;
var c, line, result;
if (!ip)
return pass();
if (!match_regexp(ip, valid_ip_regexp))
throw(~invip, "Invalid IP Address: " + ip);
if (!async)
return pass(ip);
if (!valid(connection)) {
if (!(.restart()))
return pass(ip);
}
connection = connection.write((task_id() + ":N:") + ip);
result = $scheduler.suspend(this());
if ((type(result) != 'list) || (listlen(result) != 2))
return "";
switch (result[1]) {
case "N":
throw(~address, result[2]);
case "F":
throw(~failed, result[2]);
case "G":
return result[2];
default:
$sys.log("DNS ERROR: Invalid result: " + (result.join(":")));
}
};
public method .ip() {
arg hostname;
var c, line, result;
if (!hostname)
return pass();
if ((hostname != "localhost") && (!match_regexp(hostname, valid_host_regexp)))
throw(~address, ("Invalid Internet Address: \"" + hostname) + "\"");
if (!async)
return pass(hostname);
if (!valid(connection)) {
if (!(.restart()))
return pass(hostname);
}
connection = connection.write((task_id() + ":R:") + hostname);
result = $scheduler.suspend(this());
if ((type(result) != 'list) || (listlen(result) != 2))
return "";
switch (result[1]) {
case "N":
throw(~address, result[2]);
case "F":
throw(~failed, result[2]);
case "G":
return result[2];
default:
$sys.log("DNS ERROR: Invalid result: " + (result.join(":")));
}
};
public method .parse_line() {
arg line;
var m, task, code, info;
(> .perms(caller(), $connection) <);
if ((m = regexp(line, "^([0-9]+):([a-z]):(.*)$"))) {
[task, code, info] = m;
task = toint(task);
catch any {
$scheduler.resume(task, [code, info]);
} with {
$sys.log("DNS ERROR: ");
$sys.log($parse_lib.traceback(traceback()));
}
} else {
$sys.log("DNS ERROR: Invalid Result from server: " + line);
}
};
public method .restart() {
if (starting || (!started))
return 0;
connection = 0;
catch any {
(> .startup_dns() <);
$sys.log("** Restarting async DNS lookups at " + (dnshost.join(":")));
} with {
$sys.log("** Unable to restart async DNS lookups because:");
$sys.log("** => " + ((traceback()[1])[2]));
}
return valid(connection);
};
public method .shutdown() {
arg @args;
var c;
(sender() != this()) && (> .perms(caller(), 'system) <);
c = connection;
connection = 0;
(| c.close() |);
started = 0;
};
public method .startup(): forked {
arg @args;
(> .perms(sender(), 'system) <);
.shutdown();
if (!async)
return;
catch any {
(> .startup_dns() <);
$sys.log("** Starting async DNS lookups at " + (dnshost.join(":")));
} with {
$sys.log("** Unable to startup async DNS lookups because:");
$sys.log("** => " + ((traceback()[1])[2]));
}
};
protected method .startup_dns() {
var id, tmp, x;
if (starting)
return;
started = 0;
starting = 1;
if (connection)
(| connection.close() |);
id = tosym("dns_connection");
while ((| lookup(id) |))
id = tosym("dns_connection_" + ++x);
connection = $outbound_connection.new_with(id);
if ((| connection.open_connection(@dnshost) |)) {
starting = 0;
started = 1;
return;
}
// try to exec() it, then startup again
(| $sys.startup_dnsserv() |);
$scheduler.sleep(1);
catch any {
connection.open_connection(@dnshost);
starting = 0;
} with {
(| connection.close() |);
connection = 0;
starting = 0;
if (error() == ~refused)
throw(~refused, "Unable to open connection to " + (dnshost.join(":")));
else
rethrow(error());
}
started = 1;
};
public method .valid_host_regexp() {
return valid_host_regexp;
};
public method .valid_hostname() {
arg host;
return match_regexp(host, valid_host_regexp) ? 1 : 0;
};
public method .valid_ip() {
arg ip;
return match_regexp(ip, valid_ip_regexp) ? 1 : 0;
};
public method .valid_ip_regexp() {
return valid_ip_regexp;
};