diff --git a/intel/geoip/fill_missing.go b/intel/geoip/fill_missing.go index 927baf20..624a2d5e 100644 --- a/intel/geoip/fill_missing.go +++ b/intel/geoip/fill_missing.go @@ -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}, } diff --git a/intel/geoip/location.go b/intel/geoip/location.go index f9f62f96..964d7ea0 100644 --- a/intel/geoip/location.go +++ b/intel/geoip/location.go @@ -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