Hello, I’m Joe Vennix, and this is where I blog.

I am a twenty-four year-old software security engineer. In the past I've worked on Metasploit, RetailMeNot, and clay.io, and majored in CS at the University of Texas at Austin. I like to do random security research, with a focus on Android and OS X.

I am currently busy with life and stuff, but from time to time I will post a personal project up here.

Twitter / Github

GeoIP.JS - An IP Geolocation Library for Node.JS

Posted on 25 Apr 2011
/*=========    GeoIP.JS Sample Code    ==========*/
var geo = require('./GeoIP-js/geoip.js');
geo.open({ cache: true, filename: './geoip/GeoLiteCity.dat'});
var coord = geo.lookup('74.125.227.16');
console.log(coord);
geo.close();
geo.open({ cache: true, filename: './geoip/GeoLiteCity.dat'});

Last week I needed a way to geocode IP addresses to GPS coordinates using Node.JS. I needed the geocoding done fast (locally) as I wanted to serve the coordinates within the page. I eventually found the (free) MaxMind GeoIP API which is a C library that parses their (also free) database of cities, GeoLite City, which is accurate “over 99.5% on a country level and 79% on a city level for the US within a 25 mile radius.” Good enough for me.

Unfortunately, while wrapper libraries had been written over the C API in a few different languages, Javascript was not among them. Luckily, Node.JS supports writing native extensions in C++, so with the help of a few walkthroughs and examples, I was able to hack together a native binding around the MaxMind C API.

I pushed the result to GitHub here; it might be helpful for anyone trying to figure out how to write native extensions for Node.JS. The library is far from complete: the C API allows you to pull data such as city, state, and zip code, whereas my implementation simply takes an IP and returns an array of coordinates. However, following the same model set up in my code, it would be trivial to code up similar functions that return other data.

One other thing: this library is synchronous. I thought this might cause some trouble, so I ran a few benchmarks. I found that the API often responded in less than 1ms - amazing! The API by default caches the database in memory, leading to some very fast lookups.