PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Networking » Net_DNS » Bug #7062

Update delete of NS records does not work

Details

Submitted2006-03-08 16:00 UTC
Fromsven dot hergenhahn at eur dot sas dot com
Assignedbate
StatusClosed
PackageNet_DNS
PHP Version5.0.5
OSLinux (FC2)
Roadmaps(Not assigned)

Comments

[2006-03-08 16:00 UTC] sven dot hergenhahn at eur dot sas dot com

Description:
------------
Using the functions provided to create and send an update package to delete an NS record, I get NOERROR, but the record is still there.

I thought it might have to do with the fact that the name portion is only the domain name, but when deleting an MX record, it works fine.

Thanks for checking and thanks for the modules,
Sven

Test script:
---------------
<?php
require_once 'Net/DNS.php';
$updt_data = array('rname' => '', 'zone' => 'dns.local', 'type' => 'NS', 'rdata' => 'goaway.dns.local');
deleteRR($updt_data);
$updt_data = array('rname' => '', 'zone' => 'dns.local', 'type' => 'MX', 'rdata' => '100 mx.dns.local');
deleteRR($updt_data);
function deleteRR($updt_data) {
$resolver = new Net_DNS_Resolver();
$resolver->nameservers = array('127.0.0.1');
$rname = $updt_data['rname'];
$zone = $updt_data['zone'];
$ttl = 0;
$rdata = $updt_data['rdata'];
$type = $updt_data['type'];
$packet = new Net_DNS_Packet();
$packet->header = new Net_DNS_Header();
$packet->header->id = $resolver->nextid();
$packet->header->qr = 0;
$packet->header->opcode = "UPDATE";
$packet->question[0] = new Net_DNS_Question($zone, "SOA", "IN");
$packet->answer = array();
$del_string = "$rname$zone $ttl IN $type $rdata";
$DELrr = Net_DNS_RR::new_from_string($del_string, 'del');
$packet->authority[0] = $DELrr;
$tsig = Net_DNS_RR::factory('rndckey TSIG keysecret');
$packet->additional = array($tsig);
$packet->header->qdcount = count($packet->question);
$packet->header->ancount = count($packet->answer);
$packet->header->nscount = count($packet->authority);
$packet->header->arcount = count($packet->additional);
$ans = $resolver->send_tcp($packet, $packet->data());
$ret = $ans->header->rcode;
if ($ret == 'NOERROR') { print "$ret, Deletion successful ($rname, $zone, $rdata)<br>"; }
else { print "$ret, Deletion failed ($rname, $zone, $rdata)<br>"; }
}
?>

Expected result:
----------------
NOERROR, Deletion successful (, dns.local, goaway.dns.local)
NOERROR, Deletion successful (, dns.local, 100 mx.dns.local)
The MX record is gone, but the NS record is still there...

Actual result:
--------------
Both records should have been deleted

[2006-03-09 10:12 UTC] sven dot hergenhahn at eur dot sas dot com

Hi there,

I found the problem. The function Net_DNS_RR::new_from_string does the following:

...
while ($s = array_shift($parts)) {
...

My problem was that I had already set the TTL to 0. It looks like while here takes the returned value of the assignment to check whether it is still true. As 0 is false, while ends and the variables are not set correctly.

Here's some code to verify this(along with a solution):

new_from_string("dns.local 0 IN NS lalala.dns.local");
new_from_string_fixed("dns.local 0 IN NS lalala.dns.local");

// current function, while bails out at 0
function new_from_string($rrstring){
$parts = preg_split('/[\s]+/', $rrstring);
while ($s = array_shift($parts)) {
print "s is $s<br>";
}
print "<hr>";
}

// fixed version, while bails out at end of array (count=0)
function new_from_string_fixed($rrstring){
$parts = preg_split('/[\s]+/', $rrstring);
while (count($parts) > 0) {
$s = array_shift($parts);
print "s is $s<br>";
}
print "<hr>";
}

if (!isset($name)) {
$name = ereg_replace('\.+$', '', $s);
} else if (preg_match('/^\d+$/', $s)) {
$ttl = $s;
} else if (!isset($rrclass) && ! is_null(Net_DNS::classesbyname(strtoupper($s)))) {
$rrclass = strtoupper($s);
$rdata = join(' ', $parts);
} else if (! is_null(Net_DNS::typesbyname(strtoupper($s)))) {
$rrtype = strtoupper($s);
$rdata = join(' ', $parts);
break;
} else {
break;
}
}

So for my part, the problem is solved, but I think the fix should go into your code.

Cheers,
Sven

[2006-03-09 10:23 UTC] sven dot hergenhahn at eur dot sas dot com

yep, fixed.

Thanks,
Sven

BTW: There's still a bug in Resolver.php, line 844:
socket_set_blocking($sock, false);
should be:
socket_set_blocking($sock[$ctr-1], false);