Changeset 66 for trunk/dnsbl/DNSBL.pm
- Timestamp:
- 01/05/18 18:06:47 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/dnsbl/DNSBL.pm
r54 r66 130 130 131 131 our $err; 132 our $errstr ;132 our $errstr = ''; 133 133 134 134 # basic object subs … … 184 184 "WHERE b.block >>= ? ". 185 185 "GROUP BY b.block,b.level,b.listme,o.listme ORDER BY b.block"); 186 $sthmoron = $dbh->prepare("SELECT ip,s4list FROM iplist WHERE parent = ?");186 $sthmoron = $dbh->prepare("SELECT ip,s4list,white FROM iplist WHERE parent = ?"); 187 187 } 188 188 … … 193 193 my $self = shift; 194 194 my $ip = shift; 195 my $sth = $dbh->prepare("SELECT count FROM iplist WHERE ip=?");195 my $sth = $dbh->prepare("SELECT count, exclude FROM iplist WHERE ip=?"); 196 196 $sth->execute($ip); 197 my ($ret) = $sth->fetchrow_array();197 my $ret = $sth->fetchrow_arrayref(); 198 198 return $ret; 199 199 } # end ipexists() … … 205 205 my $self = shift; 206 206 my $rep = shift; 207 my $exclude = shift; 207 208 my $sth; 208 209 my $rows = 0; … … 214 215 $rows = $sth->rows; 215 216 if ($rows == 0) { 216 $sth = $dbh->prepare("INSERT INTO iplist (ip,parent ) VALUES ".217 "(?,(SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1) )");218 $sth->execute($rep,$rep ) or die "couldn't add entry for $rep: ".$dbh->errstr."\n";217 $sth = $dbh->prepare("INSERT INTO iplist (ip,parent,exclude) VALUES ". 218 "(?,(SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1),?)"); 219 $sth->execute($rep,$rep,$exclude) or die "couldn't add entry for $rep: ".$dbh->errstr."\n"; 219 220 } elsif ($rows == 1) { 220 $sth = $dbh->prepare("UPDATE iplist SET count=count+1 WHERE ip=?"); 221 $sth = $dbh->prepare("UPDATE iplist SET count=count+1,". 222 " exclude=".($exclude ? "'y'" : "'n'"). " WHERE ip=?"); 221 223 $sth->execute($rep) or die "couldn't update listing for $rep: ".$dbh->errstr."\n"; 222 224 } else { … … 225 227 $sth = $dbh->prepare("SELECT block FROM blocks WHERE block >> ?"); 226 228 $sth->execute($rep); 227 my $updsth = $dbh->prepare("UPDATE blocks SET ipcount=(SELECT count(*) FROM iplist WHERE ip << ? ) WHERE block=?");229 my $updsth = $dbh->prepare("UPDATE blocks SET ipcount=(SELECT count(*) FROM iplist WHERE ip << ? AND exclude='n') WHERE block=?"); 228 230 while (my ($block) = $sth->fetchrow_array) { 229 231 $updsth->execute($block,$block); … … 309 311 my $orgid = shift; 310 312 my $level = shift; 313 my $exclude = shift; 314 my $comment = shift; 311 315 $blockin =~ s/^\s+//; 312 316 $blockin =~ s/\s+$//; … … 325 329 ($parent) = $sth->fetchrow_array; 326 330 } 327 $sth = $dbh->prepare("INSERT INTO blocks (block,orgid,level,parent, ipcount) VALUES (?,?,?,?,".328 "(SELECT count(*) FROM iplist WHERE ip << ? ))");329 $sth->execute("$block",$orgid,$level,$parent, "$block");331 $sth = $dbh->prepare("INSERT INTO blocks (block,orgid,level,parent,exclude,comments,ipcount) VALUES (?,?,?,?,?,?,". 332 "(SELECT count(*) FROM iplist WHERE ip << ? AND exclude='n'))"); 333 $sth->execute("$block",$orgid,$level,$parent,$exclude,$comment,"$block"); 330 334 $sth = $dbh->prepare("UPDATE iplist SET parent=? WHERE parent=? AND ip << ?"); 331 335 $sth->execute("$block",$parent,"$block"); … … 341 345 342 346 347 # Update a netblock entry. Supports (un)setting the exclude flag and the comment. 348 # Does NOT do any magic around leftover IPs within the block 349 sub updateblock { 350 my $self = shift; 351 my $blockin = shift; 352 my $orgid = shift; 353 my $level = shift; 354 my $exclude = shift; 355 my $comment = shift; 356 $blockin =~ s/^\s+//; 357 $blockin =~ s/\s+$//; 358 my $block = new NetAddr::IP "$blockin"; # need this to clean up messes like ranges. sigh. 359 360 return "$blockin not a single CIDR range" if !$block; 361 362 local $dbh->{AutoCommit} = 0; 363 local $dbh->{RaiseError} = 1; 364 365 my $sth; 366 eval { 367 my $parent = '0/0'; 368 if ($level > 0) { 369 $sth = $dbh->prepare("SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1"); 370 $sth->execute("$block"); 371 ($parent) = $sth->fetchrow_array; 372 } 373 $sth = $dbh->prepare("UPDATE blocks SET exclude = ?, comments = ?, ipcount = ". 374 "(SELECT count(*) FROM iplist WHERE ip << ? AND exclude='n')". 375 " WHERE block = ?"); 376 $sth->execute($exclude, $comment, "$block", "$block"); 377 $sth = $dbh->prepare("UPDATE iplist SET parent=? WHERE parent=? AND ip << ?"); 378 $sth->execute("$block", $parent, "$block"); 379 $dbh->commit; 380 }; 381 if ($@) { 382 my $msg = $@; 383 eval { dbh->rollback; }; 384 return "failed to update $block: $msg"; 385 } 386 # nb: no need to return anything, since the CIDR block is the key 387 } 388 389 343 390 sub blockexists { 344 391 my $self = shift; … … 351 398 352 399 353 # returns list (block, orgname) for the block that contains the passed IP.400 # returns list (block,blockcomment,orgname) for the block that contains the passed IP. 354 401 # accepts a level argument if you don't want the top-level registrar allocation block 355 402 sub getcontainer { … … 357 404 my $ip = shift; 358 405 my $level = shift || 0; 359 my $sth = $dbh->prepare("SELECT b.block, o.orgname FROM blocks b INNER JOIN orgs o ".406 my $sth = $dbh->prepare("SELECT b.block,b.comments,o.orgname FROM blocks b INNER JOIN orgs o ". 360 407 "ON b.orgid=o.orgid WHERE b.block >> ? AND b.level = ?"); 361 408 $sth->execute($ip,$level); … … 375 422 # looking for IP 376 423 377 $sth = $dbh->prepare("SELECT ip,s4list FROM iplist WHERE ip=?");424 $sth = $dbh->prepare("SELECT ip,s4list,exclude FROM iplist WHERE ip=?"); 378 425 $sth->execute($entity); 379 426 my @ret = $sth->fetchrow_array; … … 385 432 my $masklen = $1; 386 433 387 $sth = $dbh->prepare("SELECT block,listme FROM blocks WHERE block=?");434 $sth = $dbh->prepare("SELECT block,listme,exclude,ipcount FROM blocks WHERE block = ?"); 388 435 $sth->execute($entity); 389 my ($block, $listme) = $sth->fetchrow_array;436 my ($block, $listme, $exclude, $bcount) = $sth->fetchrow_array; 390 437 391 438 return if !$block; 392 439 393 $sth = $dbh->prepare("SELECT ipcount FROM blocks WHERE block = ?"); 394 $sth->execute($entity); 395 my ($bcount) = $sth->fetchrow_array; 396 my @ret = ( ($bcount >= $autolist{$masklen}), $listme); 440 my @ret = ( ($bcount >= $autolist{$masklen}), $listme, $exclude); 397 441 return @ret; 398 442 … … 433 477 my $bitmask = shift || 0; 434 478 479 if ($level == 0) { 480 $errstr = ''; 481 } 482 483 return if ($errstr =~ /no connection to the server/); 435 484 if ($level > $maxlvl) { 436 485 warn "getting too deep, breaking off! ($container, $level)\n"; … … 447 496 } 448 497 498 499 # catch database-went-away errors 500 local $dbh->{RaiseError} = 1; 501 eval { 502 503 449 504 my $sth = $dbh->prepare("SELECT count(*) FROM blocks WHERE parent = ?"); 450 505 $sth->execute($container); … … 459 514 my $listorg; 460 515 my $bcount; 516 my $bexclude; 461 517 if ($container ne '0.0.0.0/0') { 462 $sth = $dbh->prepare("SELECT b.ipcount,b.listme, o.listme ".518 $sth = $dbh->prepare("SELECT b.ipcount,b.listme,b.exclude,o.listme ". 463 519 "FROM blocks b INNER JOIN orgs o ON b.orgid=o.orgid ". 464 520 "WHERE b.block = ?"); 465 521 $sth->execute($container); 466 ($bcount,$listme,$listorg) = $sth->fetchrow_array(); 467 522 ($bcount,$listme,$bexclude,$listorg) = $sth->fetchrow_array(); 468 523 $bitmask |= $bitfields{$level-1} if $bcount >= $autolist{$masklen}; 469 524 $bitmask |= $bitfields{"block".($level-1)} if $listme; … … 473 528 # hm. can't seem to move this prepare elsewhere. :( 474 529 if ($nblocks > 0) { 475 my $sthsubblocks = $dbh->prepare("SELECT block FROM blocks ".530 my $sthsubblocks = $dbh->prepare("SELECT block,exclude FROM blocks ". 476 531 "WHERE level = ? AND parent = ?"); 477 532 $sthsubblocks->execute($level, $container); 478 while (my ($cidr) = $sthsubblocks->fetchrow_array()) { 479 $self->export($listhosts,$mode,$level+1,$cidr,$bitmask); 533 while (my ($cidr, $exclude) = $sthsubblocks->fetchrow_array()) { 534 if ($exclude) { 535 $listhosts->{$cidr} = -1; 536 } else { # don't check subtrees of an excluded block; rbldnsd doesn't support deep flip-flopping like that 537 $self->export($listhosts,$mode,$level+1,$cidr,$bitmask) 538 or die $errstr; 539 } 480 540 } 481 541 } # avoid checking content of subs if we don't have any … … 534 594 535 595 $sthmoron->execute($container); 536 while (my ($ip,$moron) = $sthmoron->fetchrow_array()) { 537 $listhosts->{$ip} |= $bitmask; 596 while (my ($ip,$moron,$exclude) = $sthmoron->fetchrow_array()) { 538 597 if ($moron) { 539 598 $listhosts->{$ip} = $bitfields{slist}; 599 } elsif ($exclude) { 600 $listhosts->{$ip} = -1; 540 601 } else { 602 $listhosts->{$ip} |= $bitmask; 541 603 $listhosts->{$ip} |= $bitfields{ip}; 542 604 } 543 605 } 606 607 608 }; # db-went-away-catching eval 609 if ($@) { 610 $errstr = $@; 611 warn "export truncated: $errstr\n"; 612 return; 613 } 614 544 615 545 616 # get IPs which for reasons unknown are apparently allocated directly from the … … 547 618 # select * from iplist where not (select count(*) from blocks where ip << block) > 0; 548 619 549 return ;620 return 1; 550 621 } # end export() 551 622
Note:
See TracChangeset
for help on using the changeset viewer.