Skip to content

Instantly share code, notes, and snippets.

@pyh
Last active July 19, 2018 20:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pyh/5224393 to your computer and use it in GitHub Desktop.
Save pyh/5224393 to your computer and use it in GitHub Desktop.
Some hacks that will map IPs to a map (with different colors). Verrrry sketchy, but "works".
"Instructions"
1) Install index.php to some webserver, and run "latlongudp.pl" on the same server.
2) Then feed IPs to the latlongudp.pl server with something like this:
tail -F /var/log/nginx/access_log|perl -e '$|=1;while(<>){print "someidentifier,$1\n" if/(\d+\.\d+\.\d+\.\d+)/}'|nc -u somenode.example.com 5001
Modify someidentifier to to fit your needs.
3) Enjoy the map...
<?php
$dbh = new SQLite3( '/dev/shm/hits.db' );
if ( isset( $_GET['g'] ) ) {
$dbh->busyTimeout(1000);
$stmt = $dbh->prepare( 'SELECT host,lat,lng FROM hit WHERE service = ? GROUP BY lat,lng ORDER BY RANDOM() LIMIT 10000;');
$stmt->bindValue(1, preg_replace( '/[^a-z]/', '', $_GET['g'] ), SQLITE3_TEXT);
$stmt->execute();
$result = $stmt->execute();
$stats = array();
while( $row = $result->fetchArray( SQLITE3_ASSOC ) ) {
$stats[] = $row;
}
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
if ( isset( $_GET['callback'] ) ) {
header("Content-type: text/javascript");
$callback = preg_replace( '/[^a-zA-Z0-9_]/', '', $_GET['callback'] );
echo "$callback(" . json_encode( $stats ) . ");";
} else {
echo json_encode( $stats );
}
} else {
?><!DOCTYPE html>
<html>
<head>
<title>anycast map</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<style>
#map canvas {
/* padding:0;margin:0;*/
/*border:1px solid #111;*/
position:absolute;
}
* {margin:0;padding:0;
}
body, html {
background:black;
}
/*
height:100%;margin:0;
padding:0px;
/*padding:10px;
background:black;
}*/
</style>
<script>
// ctx.fillStyle = "rgb(200,0,0)";
// ctx.fillRect (10, 10, 55, 50);
var map, heatmap;
var hitdata=new Array();
var running = 0;
var data = new Array();
var dcs = new Array();
var dcss = new Array();
dcss["lax"] = new Array(0,0,255); //"blue"//["rgba(0, 0, 255, 0.0)","rgba(0, 0, 255, 1.0)"];
dcss["lhr"] = new Array(255,0,0);//"red"//["rgba(255,0,0,0.0)","rgba(255,0,0,1.0)"];
dcss["iad"] = new Array(0,255,0); //"green"//["rgba(0,255,0,0.0)","rgba(0,255,0,1.0)"];
dcss["sat"] = new Array(255,127,0);//"orange"//["rgba(151,0,151,0.0)","rgba(151,0,151,1.0)"];
dcss["yyz"] = new Array(255,0,255);//"purple"//["rgba(151,0,151,0.0)","rgba(151,0,151,1.0)"];
dcss["mia"] = new Array(255,255,0); //"yellow" //
dcss["dfw"] = new Array(255,255,255); // "white" //
dcss["fra"] = new Array(0,255,255); // "light blue" //
dcss["sin"] = new Array(46,139,87); // "dark green" //
dcss["sjc"] = new Array(102,0,12); // "dark purple" //
var canvas
var image
var w=1000;
var h=500;
var ww=w/360;
var hh=h/180;
var getint
$(document).ready(function() {
get_size();
highlight();
getdata();
getint=setInterval( function(){getdata();}, 1000 );
create_canvas();
setInterval( function(){addstuff();}, 100 );
setInterval( function(){fadecanvas();}, 200 );
setInterval( function(){rotate_canvas();}, 30000 );
});
function highlight() {
if( matches = window.location.search.match(/dc=(\w+)/) ){
for( i in dcss ) {
if(i == matches[1]){
dcss[i] = new Array(255,0,0);
}else{
dcss[i] = new Array(0,0,255);
}
}
}
}
function get_size(){
var matches;
if ( matches = window.location.search.match(/w=(\d+)/) ){
w=matches[1];
ww=w/360;
}
if ( matches = window.location.search.match(/h=(\d+)/) ){
h=matches[1];
hh=h/180;
}
}
var fade=null
function rotate_canvas() {
if (document.getElementById('map').children.length > 4 && fade==null ) {
fade=document.getElementById('map').firstElementChild
}
create_canvas();
}
function fadecanvas() {
if(fade){
if(fade.style.opacity<=0.3){
document.getElementById('map').removeChild(fade);
fade=null;
}else{
fade.style.opacity-=0.1;
fade.style.filter = 'alpha(opacity=' + Math.ceil(fade.style.opacity*10) + ')';
}
}
}
function create_canvas() {
element=document.createElement('canvas');
canvas=element.getContext('2d');
canvas.canvas.width=w;
canvas.canvas.height=h;
element.style.opacity=1;
image = canvas.createImageData(w,h)
for( i in dcss ) {
dcs[i] = canvas.createImageData(1,1)
dcs[i].data[0] = dcss[i][0];
dcs[i].data[1] = dcss[i][1];
dcs[i].data[2] = dcss[i][2];
dcs[i].data[3] = 255;
}
document.getElementById('map').appendChild(element);
}
var jqxhr;
var service="wpcom";
if( matches = window.location.search.match(/s=(\w+)/) ){
service=matches[1];
}
function getdata(){
if (!running){
$.ajax(
"?g="+service,
{
cache:true,
crossDomain:true,
dataType:"jsonp",
jsonpCallback:"jsonpcallback",
timeout:4000,
}
).done( function(data) {
if( data.length ) {
hitdata=data;
hitdata.sort(function() {return 0.5 - Math.random()});
}
running=0;
}).fail(function( jqXHR, textStatus,errorThrown ) {
// alert( "Request failed: " + textStatus + " : " + errorThrown);
}).always(function() {
running=0;
// alert("foo");
});
running=1;
}
}
var max=1000;
var per_iter = 1000;
data=new Array();
function addstuff() {
for (k=0;k<per_iter;k++){
var point = hitdata.pop();
if (point){
x=Math.ceil((180+point['lng'])*ww);
y=Math.ceil((90-point['lat'])*hh);
canvas.putImageData(dcs[point['host']], x,y);
}
}
per_iter=130;
}
</script>
</head>
<body>
<div id="map"></div>
</body>
</html><?
}
#!/usr/bin/perl
# feeder on LBs
# tail -F /var/log/nginx/access_log|perl -e '$|=1;while(<>){($f,$f,$ip)=split/\s+/;$ip=~s/"//g;print "lax,$ip\n"}'|nc -u somenode.example.com 5001
use strict;
use warnings;
use IO::Socket;
use IO::Socket::INET;
use Math::Round qw( nhimult nearest );
use Geo::IP;
use DBI;
my $gi = Geo::IP->open("geocity.dat", GEOIP_MEMORY_CACHE);
my $sock = new IO::Socket::INET (
LocalPort => '5001',
Proto => 'udp',
) or die "ERROR in Socket Creation : $!\n";
# hits.db created with
#CREATE TABLE hit (time INTEGER, lat REAL,lng REAL, host TEXT);
#CREATE INDEX time ON hit (time);
my $dbh = DBI->connect("dbi:SQLite:dbname=/dev/shm/hits.db","","",{AutoCommit=>0});
$dbh->do("CREATE TABLE hit (time INTEGER, lat REAL,lng REAL, host TEXT, service TEXT);");
$dbh->do("CREATE INDEX time ON hit (time);");
$dbh->do("CREATE INDEX service ON hit (service);");
my $sth = $dbh->prepare("INSERT OR REPLACE INTO hit (lat,lng,host,time,service) VALUES(?,?,?,?,?)");
my $old_time;
my $data;
my $c=0;
$|++;
my $round=0.001;#.5;
while ($sock->recv($data, 30)) {
print ".";
print "\n" if ++$c %80==0;
chomp($data);
# print "$data\n";
my ($dc,$ip,$service) = split /,/,$data;
$service||="wpcom";
my $r=$gi->record_by_addr($ip);
next if !$r || $r->longitude==0;
my ($lat,$lng) = ($r->latitude, $r->longitude);
# gunzip(\$recieved_data => \$output);
my $curtime = time();
my $time = nhimult(2, $curtime);
if( $old_time != $time ){
$dbh->do("DELETE FROM hit WHERE time < " . ($curtime - 11) );
$dbh->commit;
$old_time=$time;
print "commit\n";
}
$sth->execute(nearest($round,$lat), nearest($round, $lng), $dc, time(),$service);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment