Using the zip code of the install site, and the known zip codes of my various head-end sites, I'm able to select the destination for the primary and secondary VPN tunnels.
It's not perfect (physical location often has little to do with network path), but it's better than nothing. I haven't decided how to handle non-US sites yet.
I'm using a database of US zip codes found here, and a very dirty perl script. The script grabs the latitude and longitude of two zip codes from the database, and prints the mileage between them as calculated using the Haversine formula for great circle distance.
It runs like this:
Christophers-MacBook-Pro:scripts chris$ zipdistance.pl 95134 60614
1837 miles
Christophers-MacBook-Pro:scripts chris$
The script:
#!/opt/local/bin/perl
use GIS::Distance;
my $dbfile="/Users/chris/Downloads/zipcode.csv";
my $lat1,$lon1,$lat2,$lon2;
sub usage{
printf "Usage: $0 <zipcode> <zipcode>\n";
exit;
}
if (@ARGV != 2) {usage;};
unless ($ARGV[0] =~ /[0-9]{5}/) {usage;}
unless ($ARGV[1] =~ /[0-9]{5}/) {usage;}
my @sorted = sort @ARGV;
open(DB, '<', $dbfile);
FIRST: while (<DB>) {
if ($_ =~ /^.$sorted[0]/) {
(my $trash,my $trash,my $trash,$lat1,$lon1)=split(",",$_);
my $i;
($i) = $lat1 =~ /"([^"]*)"/; $lat1 = $i;
($i) = $lon1 =~ /"([^"]*)"/; $lon1 = $i;
last FIRST;
}
}
SECOND: while (<DB>) {
if ($_ =~ /^.$sorted[1]/) {
(my $trash,my $trash,my $trash,$lat2,$lon2)=split(",",$_);
my $i;
($i) = $lat2 =~ /"([^"]*)"/; $lat2 = $i;
($i) = $lon2 =~ /"([^"]*)"/; $lon2 = $i;
last SECOND;
}
}
if ("$lat1" == "" || "$lat2" == "") {
printf "Unknown distance\n";
exit 1;
}
my $gis = GIS::Distance->new();
my $distance = $gis->distance( $lat1,$lon1 => $lat2,$lon2 );
printf ("%d miles\n",$distance->miles());