Skip to content

Commit

Permalink
geoip: use net_utils.get_public_ip
Browse files Browse the repository at this point in the history
with backwards compat (if locally set)
  • Loading branch information
msimerson committed Mar 29, 2014
1 parent ba2f63a commit 83bfb0a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 29 deletions.
10 changes: 3 additions & 7 deletions config/connect.geoip.ini
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
; public_ip: the public IP address of *this* mail server
; if your mail server is not bound to a public IP, you'll have to provide
; this for distance calculations to work.
; public_ip=

; show_city: show city data in logs and headers
; note: city data is less accurate than country
show_city=1
show_city=true

; show_region: show regional data (US states, CA provinces, etc..)
show_region=1
show_region=true

; enable distance calculations. If you don't use the distance, leave it
; disabled to save few CPU cycles.
calc_distance=0
calc_distance=false

; if calculating distance, an additional 'too_far' key in the geoip
; connection note can be set to true if the distance exceeds the limit (in
Expand Down
8 changes: 4 additions & 4 deletions docs/plugins/connect.geoip.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ be the IP that Haraka is bound to, but if not you'll need to supply it.
Perform the geodesic distance calculations. Calculates the distance "as the
crow flies" from the remote mail server.

- public\_ip: <IP Address>

The IP address to calculate the distance from. This will typically be
the public IP of your mail server.
This calculation requires a 'from' IP address. This will typically be the
public IP of your mail server. If Haraka is bound to a private IP, net\_utils
will attempt to determine your public IP. If that doesn't work, edit
config/smtp.ini and set `public_ip`.

- show\_city

Expand Down
38 changes: 20 additions & 18 deletions plugins/connect.geoip.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ var geoip = require('geoip-lite'),
net = require('net'),
net_utils = require('./net_utils');

var local_ip, local_geoip;

exports.hook_connect = function (next, connection) {
var plugin = this;

Expand All @@ -19,18 +17,23 @@ exports.hook_connect = function (next, connection) {

connection.results.add(plugin, r);

var cfg = plugin.config.get('connect.geoip.ini');
if (cfg.main.calc_distance) {
plugin.cfg = plugin.config.get('connect.geoip.ini', {
booleans: [
'+main.show_city',
'+main.show_region',
'-main.calc_distance',
],
});
if (plugin.cfg.main.calc_distance) {
r.distance = plugin.calculate_distance(connection, r);
}

var show = [ r.country ];
if (r.region && cfg.main.show_region) show.push(r.region);
if (r.city && cfg.main.show_city ) show.push(r.city);
if (r.distance ) show.push(r.distance+'km');
if (r.region && plugin.cfg.main.show_region) show.push(r.region);
if (r.city && plugin.cfg.main.show_city ) show.push(r.city);
if (r.distance ) show.push(r.distance+'km');

connection.results.add(plugin, {human: show.join(', '), emit:true});

return next();
};

Expand Down Expand Up @@ -63,32 +66,31 @@ exports.hook_data_post = function (next, connection) {

exports.calculate_distance = function (connection, r_geoip) {
var plugin = this;
var cfg = plugin.config.get('connect.geoip.ini');

if (!local_ip) { local_ip = cfg.main.public_ip; }
if (!local_ip) { local_ip = connection.local_ip; }
if (!local_ip) {
connection.logerror(plugin, "can't calculate distance without local IP!");
if (!plugin.local_ip) { plugin.local_ip = net_utils.get_local_ip(); };
if (!plugin.local_ip) { plugin.local_ip = plugin.cfg.main.public_ip; }
if (!plugin.local_ip) {
connection.logerror(plugin, "can't calculate distance, set public_ip in smtp.ini");
return;
}

if (!local_geoip) { local_geoip = geoip.lookup(local_ip); }
if (!local_geoip) {
if (!plugin.local_geoip) { plugin.local_geoip = geoip.lookup(plugin.local_ip); }
if (!plugin.local_geoip) {
connection.logerror(plugin, "no GeoIP results for local_ip!");
return;
}

var gcd = haversine(local_geoip.ll[0], local_geoip.ll[1], r_geoip.ll[0], r_geoip.ll[1]);
var gcd = haversine(plugin.local_geoip.ll[0], plugin.local_geoip.ll[1], r_geoip.ll[0], r_geoip.ll[1]);

connection.results.add(plugin, {distance: gcd});

if (cfg.main.too_far && (parseFloat(cfg.main.too_far) < parseFloat(gcd))) {
if (plugin.cfg.main.too_far && (parseFloat(plugin.cfg.main.too_far) < parseFloat(gcd))) {
connection.results.add(plugin, {too_far: true});
}
return gcd;
};

function haversine(lat1, lon1, lat2, lon2) {
exports.haversine = function (lat1, lon1, lat2, lon2) {
// calculate the great circle distance using the haversine formula
// found here: http://www.movable-type.co.uk/scripts/latlong.html
var R = 6371; // km
Expand Down
70 changes: 70 additions & 0 deletions tests/plugins/connect.geoip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

var stub = require('../fixtures/stub'),
Connection = require('../fixtures/stub_connection'),
Plugin = require('../fixtures/stub_plugin'),
configfile = require('../../configfile'),
config = require('../../config'),
// Header = require('../../mailheader').Header,
ResultStore = require("../../result_store");

function _set_up(callback) {
this.backup = {};

this.plugin = Plugin('connect.geoip');
this.plugin.config = config;
this.plugin.cfg = { main: {} };

this.connection = Connection.createConnection();
this.connection.results = new ResultStore(this.plugin);

callback();
}
function _tear_down(callback) {
callback();
}

// ServedBy ll: [ 47.6738, -122.3419 ],
// WMISD [ 38, -97 ]

exports.haversine = {
setUp : _set_up,
tearDown : _tear_down,
'WA to MI': function (test) {
test.expect(2);
var r = this.plugin.haversine(47.673, -122.3419, 38, -97);
test.equal(true, (r > 2000));
test.equal(true, (r < 2500));
// console.log(r);
test.done();
}
};

exports.hook_connect = {
setUp : _set_up,
tearDown : _tear_down,

'seattle: ': function (test) {
test.expect(2);
var cb = function (rc) {
test.equal(undefined, rc);
var r = this.connection.results.get('connect.geoip');
// console.log(r);
test.ok(r);
test.done();
}.bind(this);
this.connection.remote_ip='192.48.85.146';
this.plugin.hook_connect(cb, this.connection);
},
'michigan: ': function (test) {
test.expect(2);
var cb = function (rc) {
test.equal(undefined, rc);
var r = this.connection.results.get('connect.geoip');
// console.log(r);
test.ok(r);
test.done();
}.bind(this);
this.connection.remote_ip='199.176.179.3';
this.plugin.hook_connect(cb, this.connection);
},
};

0 comments on commit 83bfb0a

Please sign in to comment.