Merge pull request #492 from safing/feature/improve-location-estimation

Improve location estimation
This commit is contained in:
Daniel 2022-01-19 11:30:36 +01:00 committed by GitHub
commit f3fcee1adb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 329 additions and 308 deletions

View file

@ -1,5 +1,7 @@
package geoip
const defaultCountryBasedAccuracy = 200
// FillMissingInfo tries to fill missing location information based on the
// available existing information.
func (l *Location) FillMissingInfo() {
@ -9,253 +11,254 @@ func (l *Location) FillMissingInfo() {
l.Country.ISOCode != "" {
if c, ok := countryCoordinates[l.Country.ISOCode]; ok {
l.Coordinates = c
l.Coordinates.AccuracyRadius = defaultCountryBasedAccuracy
}
}
}
var countryCoordinates = map[string]Coordinates{
"AD": {500, 42, 1},
"AE": {500, 23, 53},
"AF": {500, 33, 67},
"AG": {500, 17, -61},
"AI": {500, 18, -63},
"AL": {500, 41, 20},
"AM": {500, 40, 45},
"AN": {500, 12, -69},
"AO": {500, -11, 17},
"AQ": {500, -75, -0},
"AR": {500, -38, -63},
"AS": {500, -14, -170},
"AT": {500, 47, 14},
"AU": {500, -25, 133},
"AW": {500, 12, -69},
"AZ": {500, 40, 47},
"BA": {500, 43, 17},
"BB": {500, 13, -59},
"BD": {500, 23, 90},
"BE": {500, 50, 4},
"BF": {500, 12, -1},
"BG": {500, 42, 25},
"BH": {500, 25, 50},
"BI": {500, -3, 29},
"BJ": {500, 9, 2},
"BM": {500, 32, -64},
"BN": {500, 4, 114},
"BO": {500, -16, -63},
"BR": {500, -14, -51},
"BS": {500, 25, -77},
"BT": {500, 27, 90},
"BV": {500, -54, 3},
"BW": {500, -22, 24},
"BY": {500, 53, 27},
"BZ": {500, 17, -88},
"CA": {500, 56, -106},
"CC": {500, -12, 96},
"CD": {500, -4, 21},
"CF": {500, 6, 20},
"CG": {500, -0, 15},
"CH": {500, 46, 8},
"CI": {500, 7, -5},
"CK": {500, -21, -159},
"CL": {500, -35, -71},
"CM": {500, 7, 12},
"CN": {500, 35, 104},
"CO": {500, 4, -74},
"CR": {500, 9, -83},
"CU": {500, 21, -77},
"CV": {500, 16, -24},
"CX": {500, -10, 105},
"CY": {500, 35, 33},
"CZ": {500, 49, 15},
"DE": {500, 51, 10},
"DJ": {500, 11, 42},
"DK": {500, 56, 9},
"DM": {500, 15, -61},
"DO": {500, 18, -70},
"DZ": {500, 28, 1},
"EC": {500, -1, -78},
"EE": {500, 58, 25},
"EG": {500, 26, 30},
"EH": {500, 24, -12},
"ER": {500, 15, 39},
"ES": {500, 40, -3},
"ET": {500, 9, 40},
"FI": {500, 61, 25},
"FJ": {500, -16, 179},
"FK": {500, -51, -59},
"FM": {500, 7, 150},
"FO": {500, 61, -6},
"FR": {500, 46, 2},
"GA": {500, -0, 11},
"GB": {500, 55, -3},
"GD": {500, 12, -61},
"GE": {500, 42, 43},
"GF": {500, 3, -53},
"GG": {500, 49, -2},
"GH": {500, 7, -1},
"GI": {500, 36, -5},
"GL": {500, 71, -42},
"GM": {500, 13, -15},
"GN": {500, 9, -9},
"GP": {500, 16, -62},
"GQ": {500, 1, 10},
"GR": {500, 39, 21},
"GS": {500, -54, -36},
"GT": {500, 15, -90},
"GU": {500, 13, 144},
"GW": {500, 11, -15},
"GY": {500, 4, -58},
"GZ": {500, 31, 34},
"HK": {500, 22, 114},
"HM": {500, -53, 73},
"HN": {500, 15, -86},
"HR": {500, 45, 15},
"HT": {500, 18, -72},
"HU": {500, 47, 19},
"ID": {500, -0, 113},
"IE": {500, 53, -8},
"IL": {500, 31, 34},
"IM": {500, 54, -4},
"IN": {500, 20, 78},
"IO": {500, -6, 71},
"IQ": {500, 33, 43},
"IR": {500, 32, 53},
"IS": {500, 64, -19},
"IT": {500, 41, 12},
"JE": {500, 49, -2},
"JM": {500, 18, -77},
"JO": {500, 30, 36},
"JP": {500, 36, 138},
"KE": {500, -0, 37},
"KG": {500, 41, 74},
"KH": {500, 12, 104},
"KI": {500, -3, -168},
"KM": {500, -11, 43},
"KN": {500, 17, -62},
"KP": {500, 40, 127},
"KR": {500, 35, 127},
"KW": {500, 29, 47},
"KY": {500, 19, -80},
"KZ": {500, 48, 66},
"LA": {500, 19, 102},
"LB": {500, 33, 35},
"LC": {500, 13, -60},
"LI": {500, 47, 9},
"LK": {500, 7, 80},
"LR": {500, 6, -9},
"LS": {500, -29, 28},
"LT": {500, 55, 23},
"LU": {500, 49, 6},
"LV": {500, 56, 24},
"LY": {500, 26, 17},
"MA": {500, 31, -7},
"MC": {500, 43, 7},
"MD": {500, 47, 28},
"ME": {500, 42, 19},
"MG": {500, -18, 46},
"MH": {500, 7, 171},
"MK": {500, 41, 21},
"ML": {500, 17, -3},
"MM": {500, 21, 95},
"MN": {500, 46, 103},
"MO": {500, 22, 113},
"MP": {500, 17, 145},
"MQ": {500, 14, -61},
"MR": {500, 21, -10},
"MS": {500, 16, -62},
"MT": {500, 35, 14},
"MU": {500, -20, 57},
"MV": {500, 3, 73},
"MW": {500, -13, 34},
"MX": {500, 23, -102},
"MY": {500, 4, 101},
"MZ": {500, -18, 35},
"NA": {500, -22, 18},
"NC": {500, -20, 165},
"NE": {500, 17, 8},
"NF": {500, -29, 167},
"NG": {500, 9, 8},
"NI": {500, 12, -85},
"NL": {500, 52, 5},
"NO": {500, 60, 8},
"NP": {500, 28, 84},
"NR": {500, -0, 166},
"NU": {500, -19, -169},
"NZ": {500, -40, 174},
"OM": {500, 21, 55},
"PA": {500, 8, -80},
"PE": {500, -9, -75},
"PF": {500, -17, -149},
"PG": {500, -6, 143},
"PH": {500, 12, 121},
"PK": {500, 30, 69},
"PL": {500, 51, 19},
"PM": {500, 46, -56},
"PN": {500, -24, -127},
"PR": {500, 18, -66},
"PS": {500, 31, 35},
"PT": {500, 39, -8},
"PW": {500, 7, 134},
"PY": {500, -23, -58},
"QA": {500, 25, 51},
"RE": {500, -21, 55},
"RO": {500, 45, 24},
"RS": {500, 44, 21},
"RU": {500, 61, 105},
"RW": {500, -1, 29},
"SA": {500, 23, 45},
"SB": {500, -9, 160},
"SC": {500, -4, 55},
"SD": {500, 12, 30},
"SE": {500, 60, 18},
"SG": {500, 1, 103},
"SH": {500, -24, -10},
"SI": {500, 46, 14},
"SJ": {500, 77, 23},
"SK": {500, 48, 19},
"SL": {500, 8, -11},
"SM": {500, 43, 12},
"SN": {500, 14, -14},
"SO": {500, 5, 46},
"SR": {500, 3, -56},
"ST": {500, 0, 6},
"SV": {500, 13, -88},
"SY": {500, 34, 38},
"SZ": {500, -26, 31},
"TC": {500, 21, -71},
"TD": {500, 15, 18},
"TF": {500, -49, 69},
"TG": {500, 8, 0},
"TH": {500, 15, 100},
"TJ": {500, 38, 71},
"TK": {500, -8, -171},
"TL": {500, -8, 125},
"TM": {500, 38, 59},
"TN": {500, 33, 9},
"TO": {500, -21, -175},
"TR": {500, 38, 35},
"TT": {500, 10, -61},
"TV": {500, -7, 177},
"TW": {500, 23, 120},
"TZ": {500, -6, 34},
"UA": {500, 48, 31},
"UG": {500, 1, 32},
"US": {500, 37, -95},
"UY": {500, -32, -55},
"UZ": {500, 41, 64},
"VA": {500, 41, 12},
"VC": {500, 12, -61},
"VE": {500, 6, -66},
"VG": {500, 18, -64},
"VI": {500, 18, -64},
"VN": {500, 14, 108},
"VU": {500, -15, 166},
"WF": {500, -13, -177},
"WS": {500, -13, -172},
"XK": {500, 42, 20},
"YE": {500, 15, 48},
"YT": {500, -12, 45},
"ZA": {500, -30, 22},
"ZM": {500, -13, 27},
"ZW": {500, -19, 29},
"AD": {Latitude: 42, Longitude: 1},
"AE": {Latitude: 23, Longitude: 53},
"AF": {Latitude: 33, Longitude: 67},
"AG": {Latitude: 17, Longitude: -61},
"AI": {Latitude: 18, Longitude: -63},
"AL": {Latitude: 41, Longitude: 20},
"AM": {Latitude: 40, Longitude: 45},
"AN": {Latitude: 12, Longitude: -69},
"AO": {Latitude: -11, Longitude: 17},
"AQ": {Latitude: -75, Longitude: -0},
"AR": {Latitude: -38, Longitude: -63},
"AS": {Latitude: -14, Longitude: -170},
"AT": {Latitude: 47, Longitude: 14},
"AU": {Latitude: -25, Longitude: 133},
"AW": {Latitude: 12, Longitude: -69},
"AZ": {Latitude: 40, Longitude: 47},
"BA": {Latitude: 43, Longitude: 17},
"BB": {Latitude: 13, Longitude: -59},
"BD": {Latitude: 23, Longitude: 90},
"BE": {Latitude: 50, Longitude: 4},
"BF": {Latitude: 12, Longitude: -1},
"BG": {Latitude: 42, Longitude: 25},
"BH": {Latitude: 25, Longitude: 50},
"BI": {Latitude: -3, Longitude: 29},
"BJ": {Latitude: 9, Longitude: 2},
"BM": {Latitude: 32, Longitude: -64},
"BN": {Latitude: 4, Longitude: 114},
"BO": {Latitude: -16, Longitude: -63},
"BR": {Latitude: -14, Longitude: -51},
"BS": {Latitude: 25, Longitude: -77},
"BT": {Latitude: 27, Longitude: 90},
"BV": {Latitude: -54, Longitude: 3},
"BW": {Latitude: -22, Longitude: 24},
"BY": {Latitude: 53, Longitude: 27},
"BZ": {Latitude: 17, Longitude: -88},
"CA": {Latitude: 56, Longitude: -106},
"CC": {Latitude: -12, Longitude: 96},
"CD": {Latitude: -4, Longitude: 21},
"CF": {Latitude: 6, Longitude: 20},
"CG": {Latitude: -0, Longitude: 15},
"CH": {Latitude: 46, Longitude: 8},
"CI": {Latitude: 7, Longitude: -5},
"CK": {Latitude: -21, Longitude: -159},
"CL": {Latitude: -35, Longitude: -71},
"CM": {Latitude: 7, Longitude: 12},
"CN": {Latitude: 35, Longitude: 104},
"CO": {Latitude: 4, Longitude: -74},
"CR": {Latitude: 9, Longitude: -83},
"CU": {Latitude: 21, Longitude: -77},
"CV": {Latitude: 16, Longitude: -24},
"CX": {Latitude: -10, Longitude: 105},
"CY": {Latitude: 35, Longitude: 33},
"CZ": {Latitude: 49, Longitude: 15},
"DE": {Latitude: 51, Longitude: 10},
"DJ": {Latitude: 11, Longitude: 42},
"DK": {Latitude: 56, Longitude: 9},
"DM": {Latitude: 15, Longitude: -61},
"DO": {Latitude: 18, Longitude: -70},
"DZ": {Latitude: 28, Longitude: 1},
"EC": {Latitude: -1, Longitude: -78},
"EE": {Latitude: 58, Longitude: 25},
"EG": {Latitude: 26, Longitude: 30},
"EH": {Latitude: 24, Longitude: -12},
"ER": {Latitude: 15, Longitude: 39},
"ES": {Latitude: 40, Longitude: -3},
"ET": {Latitude: 9, Longitude: 40},
"FI": {Latitude: 61, Longitude: 25},
"FJ": {Latitude: -16, Longitude: 179},
"FK": {Latitude: -51, Longitude: -59},
"FM": {Latitude: 7, Longitude: 150},
"FO": {Latitude: 61, Longitude: -6},
"FR": {Latitude: 46, Longitude: 2},
"GA": {Latitude: -0, Longitude: 11},
"GB": {Latitude: 55, Longitude: -3},
"GD": {Latitude: 12, Longitude: -61},
"GE": {Latitude: 42, Longitude: 43},
"GF": {Latitude: 3, Longitude: -53},
"GG": {Latitude: 49, Longitude: -2},
"GH": {Latitude: 7, Longitude: -1},
"GI": {Latitude: 36, Longitude: -5},
"GL": {Latitude: 71, Longitude: -42},
"GM": {Latitude: 13, Longitude: -15},
"GN": {Latitude: 9, Longitude: -9},
"GP": {Latitude: 16, Longitude: -62},
"GQ": {Latitude: 1, Longitude: 10},
"GR": {Latitude: 39, Longitude: 21},
"GS": {Latitude: -54, Longitude: -36},
"GT": {Latitude: 15, Longitude: -90},
"GU": {Latitude: 13, Longitude: 144},
"GW": {Latitude: 11, Longitude: -15},
"GY": {Latitude: 4, Longitude: -58},
"GZ": {Latitude: 31, Longitude: 34},
"HK": {Latitude: 22, Longitude: 114},
"HM": {Latitude: -53, Longitude: 73},
"HN": {Latitude: 15, Longitude: -86},
"HR": {Latitude: 45, Longitude: 15},
"HT": {Latitude: 18, Longitude: -72},
"HU": {Latitude: 47, Longitude: 19},
"ID": {Latitude: -0, Longitude: 113},
"IE": {Latitude: 53, Longitude: -8},
"IL": {Latitude: 31, Longitude: 34},
"IM": {Latitude: 54, Longitude: -4},
"IN": {Latitude: 20, Longitude: 78},
"IO": {Latitude: -6, Longitude: 71},
"IQ": {Latitude: 33, Longitude: 43},
"IR": {Latitude: 32, Longitude: 53},
"IS": {Latitude: 64, Longitude: -19},
"IT": {Latitude: 41, Longitude: 12},
"JE": {Latitude: 49, Longitude: -2},
"JM": {Latitude: 18, Longitude: -77},
"JO": {Latitude: 30, Longitude: 36},
"JP": {Latitude: 36, Longitude: 138},
"KE": {Latitude: -0, Longitude: 37},
"KG": {Latitude: 41, Longitude: 74},
"KH": {Latitude: 12, Longitude: 104},
"KI": {Latitude: -3, Longitude: -168},
"KM": {Latitude: -11, Longitude: 43},
"KN": {Latitude: 17, Longitude: -62},
"KP": {Latitude: 40, Longitude: 127},
"KR": {Latitude: 35, Longitude: 127},
"KW": {Latitude: 29, Longitude: 47},
"KY": {Latitude: 19, Longitude: -80},
"KZ": {Latitude: 48, Longitude: 66},
"LA": {Latitude: 19, Longitude: 102},
"LB": {Latitude: 33, Longitude: 35},
"LC": {Latitude: 13, Longitude: -60},
"LI": {Latitude: 47, Longitude: 9},
"LK": {Latitude: 7, Longitude: 80},
"LR": {Latitude: 6, Longitude: -9},
"LS": {Latitude: -29, Longitude: 28},
"LT": {Latitude: 55, Longitude: 23},
"LU": {Latitude: 49, Longitude: 6},
"LV": {Latitude: 56, Longitude: 24},
"LY": {Latitude: 26, Longitude: 17},
"MA": {Latitude: 31, Longitude: -7},
"MC": {Latitude: 43, Longitude: 7},
"MD": {Latitude: 47, Longitude: 28},
"ME": {Latitude: 42, Longitude: 19},
"MG": {Latitude: -18, Longitude: 46},
"MH": {Latitude: 7, Longitude: 171},
"MK": {Latitude: 41, Longitude: 21},
"ML": {Latitude: 17, Longitude: -3},
"MM": {Latitude: 21, Longitude: 95},
"MN": {Latitude: 46, Longitude: 103},
"MO": {Latitude: 22, Longitude: 113},
"MP": {Latitude: 17, Longitude: 145},
"MQ": {Latitude: 14, Longitude: -61},
"MR": {Latitude: 21, Longitude: -10},
"MS": {Latitude: 16, Longitude: -62},
"MT": {Latitude: 35, Longitude: 14},
"MU": {Latitude: -20, Longitude: 57},
"MV": {Latitude: 3, Longitude: 73},
"MW": {Latitude: -13, Longitude: 34},
"MX": {Latitude: 23, Longitude: -102},
"MY": {Latitude: 4, Longitude: 101},
"MZ": {Latitude: -18, Longitude: 35},
"NA": {Latitude: -22, Longitude: 18},
"NC": {Latitude: -20, Longitude: 165},
"NE": {Latitude: 17, Longitude: 8},
"NF": {Latitude: -29, Longitude: 167},
"NG": {Latitude: 9, Longitude: 8},
"NI": {Latitude: 12, Longitude: -85},
"NL": {Latitude: 52, Longitude: 5},
"NO": {Latitude: 60, Longitude: 8},
"NP": {Latitude: 28, Longitude: 84},
"NR": {Latitude: -0, Longitude: 166},
"NU": {Latitude: -19, Longitude: -169},
"NZ": {Latitude: -40, Longitude: 174},
"OM": {Latitude: 21, Longitude: 55},
"PA": {Latitude: 8, Longitude: -80},
"PE": {Latitude: -9, Longitude: -75},
"PF": {Latitude: -17, Longitude: -149},
"PG": {Latitude: -6, Longitude: 143},
"PH": {Latitude: 12, Longitude: 121},
"PK": {Latitude: 30, Longitude: 69},
"PL": {Latitude: 51, Longitude: 19},
"PM": {Latitude: 46, Longitude: -56},
"PN": {Latitude: -24, Longitude: -127},
"PR": {Latitude: 18, Longitude: -66},
"PS": {Latitude: 31, Longitude: 35},
"PT": {Latitude: 39, Longitude: -8},
"PW": {Latitude: 7, Longitude: 134},
"PY": {Latitude: -23, Longitude: -58},
"QA": {Latitude: 25, Longitude: 51},
"RE": {Latitude: -21, Longitude: 55},
"RO": {Latitude: 45, Longitude: 24},
"RS": {Latitude: 44, Longitude: 21},
"RU": {Latitude: 61, Longitude: 105},
"RW": {Latitude: -1, Longitude: 29},
"SA": {Latitude: 23, Longitude: 45},
"SB": {Latitude: -9, Longitude: 160},
"SC": {Latitude: -4, Longitude: 55},
"SD": {Latitude: 12, Longitude: 30},
"SE": {Latitude: 60, Longitude: 18},
"SG": {Latitude: 1, Longitude: 103},
"SH": {Latitude: -24, Longitude: -10},
"SI": {Latitude: 46, Longitude: 14},
"SJ": {Latitude: 77, Longitude: 23},
"SK": {Latitude: 48, Longitude: 19},
"SL": {Latitude: 8, Longitude: -11},
"SM": {Latitude: 43, Longitude: 12},
"SN": {Latitude: 14, Longitude: -14},
"SO": {Latitude: 5, Longitude: 46},
"SR": {Latitude: 3, Longitude: -56},
"ST": {Latitude: 0, Longitude: 6},
"SV": {Latitude: 13, Longitude: -88},
"SY": {Latitude: 34, Longitude: 38},
"SZ": {Latitude: -26, Longitude: 31},
"TC": {Latitude: 21, Longitude: -71},
"TD": {Latitude: 15, Longitude: 18},
"TF": {Latitude: -49, Longitude: 69},
"TG": {Latitude: 8, Longitude: 0},
"TH": {Latitude: 15, Longitude: 100},
"TJ": {Latitude: 38, Longitude: 71},
"TK": {Latitude: -8, Longitude: -171},
"TL": {Latitude: -8, Longitude: 125},
"TM": {Latitude: 38, Longitude: 59},
"TN": {Latitude: 33, Longitude: 9},
"TO": {Latitude: -21, Longitude: -175},
"TR": {Latitude: 38, Longitude: 35},
"TT": {Latitude: 10, Longitude: -61},
"TV": {Latitude: -7, Longitude: 177},
"TW": {Latitude: 23, Longitude: 120},
"TZ": {Latitude: -6, Longitude: 34},
"UA": {Latitude: 48, Longitude: 31},
"UG": {Latitude: 1, Longitude: 32},
"US": {Latitude: 37, Longitude: -95},
"UY": {Latitude: -32, Longitude: -55},
"UZ": {Latitude: 41, Longitude: 64},
"VA": {Latitude: 41, Longitude: 12},
"VC": {Latitude: 12, Longitude: -61},
"VE": {Latitude: 6, Longitude: -66},
"VG": {Latitude: 18, Longitude: -64},
"VI": {Latitude: 18, Longitude: -64},
"VN": {Latitude: 14, Longitude: 108},
"VU": {Latitude: -15, Longitude: 166},
"WF": {Latitude: -13, Longitude: -177},
"WS": {Latitude: -13, Longitude: -172},
"XK": {Latitude: 42, Longitude: 20},
"YE": {Latitude: 15, Longitude: 48},
"YT": {Latitude: -12, Longitude: 45},
"ZA": {Latitude: -30, Longitude: 22},
"ZM": {Latitude: -13, Longitude: 27},
"ZW": {Latitude: -19, Longitude: 29},
}

View file

@ -8,7 +8,8 @@ import (
)
const (
earthCircumferenceInKm float64 = 40100 // earth circumference in km
earthCircumferenceInKm = 40100 // earth circumference in km
defaultLocationAccuracy = 100
)
// Location holds information regarding the geographical and network location of an IP address.
@ -30,52 +31,75 @@ type Coordinates struct {
Longitude float64 `maxminddb:"longitude"`
}
/*
Location Estimation
Distance Value
- 0: Other side of the Internet.
- 100: Very near, up to same network / datacenter.
Weighting Goal
- Exposure to different networks shall be limited as much as possible.
- A single network should not see a connection over a large distance.
- Latency should be low.
Weighting Intentions
- Being on the same continent is better than being in the same AS.
- Being in the same country is better than having low coordinate distance.
- Coordinate distance is only a tie breaker, as accuracy varies heavily.
- Same AS with lower coordinate distance beats being on the same continent.
Weighting Configuration
*/
const (
weightContinentMatch = 25
weightCountryMatch = 20
weightASOrgMatch = 15
weightASNMatch = 10
weightCoordinateDistance = 30
)
/*
About the Accuracy Radius
- Range: 1-1000
- Seen values (estimation): 1,5,10,20,50,100,200,500,1000
- The default seems to be 100.
Cxamples
- 1.1.1/24 has 1000: Anycast
- 8.8.0/19 has 1000: Anycast
- 8.8.52/22 has 1: City of Westfield
Conclusion
- Ignore or penalize high accuracy radius.
*/
// EstimateNetworkProximity aims to calculate the distance between two network locations. Returns a proximity value between 0 (far away) and 100 (nearby).
func (l *Location) EstimateNetworkProximity(to *Location) (proximity int) {
/*
Distance Value
- 0: Other side of the Internet.
- 100: Very near, up to same network / datacenter.
Weighting Goal
- Exposure to different networks shall be limited as much as possible.
- A single network should not see a connection over a large distance.
- Latency should be low.
Weighting Intentions
- Being on the same continent is better than being in the same AS.
- Being in the same country is better than having low coordinate distance.
- Coordinate distance is only a tie breaker, as accuracy varies heavily.
- Same AS with lower coordinate distance beats being on the same continent.
Weighting Configuration
- Continent match: 30
- Country match: 25
- ASOrg match: 20
- ASN match: 15
- Coordinate distance: 0-10
*/
if l.Continent.Code != "" &&
l.Continent.Code == to.Continent.Code {
proximity += 30
if l.Country.ISOCode != "" &&
l.Country.ISOCode == to.Country.ISOCode {
proximity += 25
}
func (l *Location) EstimateNetworkProximity(to *Location) (proximity float32) {
switch {
case l.Country.ISOCode != "" && l.Country.ISOCode == to.Country.ISOCode:
// Rely more on the Country Code data, as it is more accurate than the
// Continent Code, especially when combining location data from multiple
// sources.
proximity += weightContinentMatch + weightCountryMatch
case l.Continent.Code != "" && l.Continent.Code == to.Continent.Code:
proximity += weightContinentMatch
}
if l.AutonomousSystemOrganization != "" &&
l.AutonomousSystemOrganization == to.AutonomousSystemOrganization {
proximity += 20
if l.AutonomousSystemNumber != 0 &&
l.AutonomousSystemNumber == to.AutonomousSystemNumber {
proximity += 15
}
switch {
case l.AutonomousSystemNumber != 0 && l.AutonomousSystemNumber == to.AutonomousSystemNumber:
// Rely more on the ASN data, as it is more accurate than the ASOrg data,
// especially when combining location data from multiple sources.
proximity += weightASOrgMatch + weightASNMatch
case l.AutonomousSystemOrganization != "" && l.AutonomousSystemOrganization == to.AutonomousSystemOrganization:
proximity += weightASOrgMatch
}
// Check coordinates and adjust accuracy value.
@ -91,23 +115,10 @@ func (l *Location) EstimateNetworkProximity(to *Location) (proximity int) {
accuracy = to.Coordinates.AccuracyRadius
}
/*
About the Accuracy Radius
- Range: 1-1000
- Seen values (estimation): 1,5,10,20,50,100,200,500,1000
- The default seems to be 100.
Cxamples
- 1.1.1/24 has 1000: Anycast
- 8.8.0/19 has 1000: Anycast
- 8.8.52/22 has 1: City of Westfield
Conclusion
- Ignore or penalize high accuracy radius.
*/
// Apply the default location accuracy if there is none.
if accuracy == 0 {
accuracy = defaultLocationAccuracy
}
// Calculate coordinate distance in kilometers.
fromCoords := haversine.Coord{Lat: l.Coordinates.Latitude, Lon: l.Coordinates.Longitude}
@ -116,14 +127,21 @@ func (l *Location) EstimateNetworkProximity(to *Location) (proximity int) {
if km <= 50 && accuracy <= 100 {
// Give a flat out ten for highly accurate coordinates within 50km.
proximity += 10
proximity += weightCoordinateDistance
} else {
// Else, take a percentage.
distanceInPercent := (earthCircumferenceInKm - km) * 100 / earthCircumferenceInKm
proximityInPercent := (earthCircumferenceInKm - km) / earthCircumferenceInKm
// Apply penalty for locations with low accuracy (targeting accuracy radius >100).
// Take away at most 50% of the weight through inaccuracy.
accuracyModifier := 1 - float64(accuracy)/2000
proximity += int(distanceInPercent * 0.10 * accuracyModifier)
// Add proximiy weight.
proximity += float32(
weightCoordinateDistance * // Maxmimum weight for this data point.
proximityInPercent * // Range: 0-1
accuracyModifier, // Range: 0.5-1
)
}
return proximity