- Timestamp:
- 10/09/07 13:06:45 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/cgi-bin/IPDB.pm
r362 r365 16 16 use DBI; 17 17 use Net::SMTP; 18 use NetAddr::IP qw( Compact ); 18 19 use POSIX; 19 20 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); … … 24 25 %disp_alloctypes %list_alloctypes %def_custids @citylist @poplist @masterblocks 25 26 %allocated %free %routed %bigfree %IPDBacl 26 &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock & deleteBlock27 & getBlockData &mailNotify27 &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock &addMaster 28 &deleteBlock &getBlockData &mailNotify 28 29 ); 29 30 … … 33 34 @masterblocks %allocated %free %routed %bigfree %IPDBacl 34 35 &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock 35 & deleteBlock &getBlockData &mailNotify36 &addMaster &deleteBlock &getBlockData &mailNotify 36 37 )] 37 38 ); … … 179 180 # $dbh->disconnect; 180 181 } # end checkDBSanity 182 183 184 ## IPDB::addMaster() 185 # Does all the magic necessary to sucessfully add a master block 186 # Requires database handle, block to add 187 # Returns failure code and error message or success code and "message" 188 sub addMaster { 189 my $dbh = shift; 190 my $cidr = new NetAddr::IP shift; 191 192 # Allow transactions, and raise an exception on errors so we can catch it later. 193 # Use local to make sure these get "reset" properly on exiting this block 194 local $dbh->{AutoCommit} = 0; 195 local $dbh->{RaiseError} = 1; 196 197 # Wrap all the SQL in a transaction 198 eval { 199 my $sth = $dbh->prepare("select count(*) from masterblocks where cidr <<= '$cidr'"); 200 $sth->execute; 201 my @data = $sth->fetchrow_array; 202 203 if ($data[0] eq 0) { 204 # First case - master is brand-spanking-new. 205 ##fixme: rwhois should be globally-flagable somewhere, much like a number of other things 206 ## maybe a db table called "config"? 207 $sth = $dbh->prepare("insert into masterblocks (cidr,rwhois) values ('$cidr','y')"); 208 $sth->execute; 209 210 # Unrouted blocks aren't associated with a city (yet). We don't rely on this 211 # elsewhere though; legacy data may have traps and pitfalls in it to break this. 212 # Thus the "routed" flag. 213 214 $sth = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed)". 215 " values ('$cidr',".$cidr->masklen.",'<NULL>','n')"); 216 $sth->execute; 217 218 # If we get here, everything is happy. Commit changes. 219 $dbh->commit; 220 221 } # new master does not contain existing master(s) 222 else { 223 224 # collect the master(s) we're going to absorb, and snag the longest netmask while we're at it. 225 my $smallmask = $cidr->masklen; 226 $sth = $dbh->prepare("select cidr as mask from masterblocks where cidr <<= '$cidr'"); 227 $sth->execute; 228 my @cmasters; 229 while (my @data = $sth->fetchrow_array) { 230 my $master = new NetAddr::IP $data[0]; 231 push @cmasters, $master; 232 $smallmask = $master->masklen if $master->masklen > $smallmask; 233 } 234 235 # split the new master, and keep only those blocks not part of an existing master 236 my @blocklist; 237 foreach my $seg ($cidr->split($smallmask)) { 238 my $contained = 0; 239 foreach my $master (@cmasters) { 240 $contained = 1 if $master->contains($seg); 241 } 242 push @blocklist, $seg if !$contained; 243 } 244 245 # collect the unrouted free blocks within the new master 246 $sth = $dbh->prepare("select cidr from freeblocks where ". 247 "maskbits>=$smallmask and cidr <<= '$cidr' and routed='n'"); 248 $sth->execute; 249 while (my @data = $sth->fetchrow_array) { 250 my $freeblock = new NetAddr::IP $data[0]; 251 push @blocklist, $freeblock; 252 } 253 254 # combine the set of free blocks we should have now. 255 @blocklist = Compact(@blocklist); 256 257 # and now insert the new data. Make sure to delete old masters too. 258 259 # freeblocks 260 $sth = $dbh->prepare("delete from freeblocks where cidr <<= ?"); 261 my $sth2 = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed) values (?,?,'<NULL>','n')"); 262 foreach my $newblock (@blocklist) { 263 $sth->execute("$newblock"); 264 $sth2->execute("$newblock", $newblock->masklen); 265 } 266 267 # master 268 $sth = $dbh->prepare("delete from masterblocks where cidr <<= '$cidr'"); 269 $sth->execute; 270 $sth = $dbh->prepare("insert into masterblocks (cidr,rwhois) values ('$cidr','y')"); 271 $sth->execute; 272 273 # *whew* If we got here, we likely suceeded. 274 $dbh->commit; 275 } # new master contained existing master(s) 276 }; # end eval 277 278 if ($@) { 279 my $msg = $@; 280 eval { $dbh->rollback; }; 281 return ('FAIL',$msg); 282 } else { 283 return ('OK','OK'); 284 } 285 } # end addMaster 181 286 182 287 … … 511 616 $sth = $dbh->prepare("delete from masterblocks where cidr='$cidr'"); 512 617 $sth->execute; 513 $sth = $dbh->prepare("delete from freeblocks where cidr ='$cidr'");618 $sth = $dbh->prepare("delete from freeblocks where cidr <<= '$cidr'"); 514 619 $sth->execute; 515 620 $dbh->commit;
Note:
See TracChangeset
for help on using the changeset viewer.