[OpenSIPS-Users] Calculate the nearest destination based on GeoIP

Wed Mar 20 06:34:34 EDT 2019

in addition, for now I use logic like this:

route[GEOIP_DST] {
# lookup by IP
if (!mmg_lookup("lon:lat","\$avp(upstreamip)","\$avp(lat_lon)")) {
xlog("L_INFO", "[GEOIP_DST] \$rm \$avp(upstreamip) - is not external IP address\n");
return(-1);
}

xlog("L_INFO", "[GEOIP_DST] \$C(gx)\$rm - \$avp(upstreamip) is external. will calculate the nearest destination\$C(xx)\n");
xlog("L_NOTICE","[GEOIP_DST] \$rm - source IP=\$avp(upstreamip) latitude:\$(avp(lat_lon)[0]) and longitude:\$(avp(lat_lon)[1])\n");

# set default vars
\$var(rad) = 6372; # len earth in km
\$var(min) = \$var(rad); # min len between the client and candidate in km
\$var(pi) = "3.141492";
\$var(id) = 0; # start search from this id position in dispatcher table from attrs column
\$var(maxid) = 50; # finish to this position

math_eval("\$(avp(lat_lon)[0]) * \$var(pi) / 180", "\$var(lat1)");
math_eval("\$(avp(lat_lon)[1]) * \$var(pi) / 180", "\$var(lon1)");

while ( \$var(id) < \$var(maxid) ) {
\$var(dst) = \$sql_cached_value(id:destination:\$var(id));
\$var(coo) = \$sql_cached_value(id:attrs:\$var(id));
if (\$var(coo)) {
math_eval("\$(var(coo){s.select,0,,}) * \$var(pi) / 180","\$var(lat2)");
math_eval("\$(var(coo){s.select,1,,}) * \$var(pi) / 180","\$var(lon2)");
# calculate trigonometry
math_eval("sin(\$var(lat1))", "\$var(slat1)");
math_eval("sin(\$var(lat2))", "\$var(slat2)");
math_eval("cos(\$var(lat1))", "\$var(clat1)");
math_eval("cos(\$var(lat2))", "\$var(clat2)");
math_eval("\$var(lon2) - \$var(lon1)", "\$var(delta)");
math_eval("cos(\$var(delta))", "\$var(cdelta)");
math_eval("\$var(slat1) * \$var(slat2) + \$var(clat1) * \$var(clat2) * \$var(cdelta)", "\$var(cdw)");
math_round("\$var(cdw)", "\$var(cd)", "4");
math_eval("acos(\$var(cd))", "\$var(d)");
# or just use linear algebra
#math_eval("sqrt(((\$(avp(lat_lon)[0]) - \$(avp(g:coo){s.select,0,,})) ^ 2) + ((\$(avp(lat_lon)[1]) - \$(avp(g:coo){s.select,1,,})) ^ 2))", "\$var(len)");
# cut float pont, use decimal
\$var(len) = \$(var(len){s.select,0,.}{s.int});
# calculate minimal destination
if ( \$var(len) < \$var(min) ) {
xlog("L_INFO", "===== dst=\$var(dst) len=\$var(len) min=\$var(min) id=\$var(id) =====\n");
\$var(min) = \$var(len);
\$avp(media_dst) = \$var(dst);
}
}
# counter item
\$var(id) = \$var(id) + 1;
}
xlog("L_NOTICE", "[GEOIP_DST] \$rm - selected destination \$C(gx)\$avp(media_dst)\$C(xx)\n");
return(1);
}

-----Original Message-----
Sent: Wednesday, March 20, 2019 1:00 PM
To: 'users at lists.opensips.org' <users at lists.opensips.org>
Subject: Calculate the nearest destination based on GeoIP

Hi there,
Maybe you know the best way to calculate the nearest routing point based on geoip data?
an example:
I have 3 rtpengine relays on a different country, and I can set its geo-coordinate in DB and set id for each of them via rtpengine_use_set() function in the routing script.
Also, I have goip lookup via mmg_lookup() function that can give me a coordinate a caller by IP address.
A caller comes from the country that _doesn't have_ rtpengine relay and I need to calculate the nearest rtpengine id for set it as prefer based on its IP address Any advice is appreciated.
Thanks