public void Lookup(IPAddress ip, Action <GeoInfo> callback) { uint ipInt = Ip4Utils.ToInt(ip); GeoInfo geoInfo = null; lock (cache) { if (cache.TryGetValue(ipInt, out var cached)) { geoInfo = cached as GeoInfo; } if (geoInfo == null) { if (this.usageExceeded == DateTime.UtcNow.Date) { return; } if (cached == null) { cache.Add(ipInt, callback); this.queue.Add(ip); } else { var callbacks = (Action <GeoInfo>)cached; callbacks += callback; cache[ipInt] = callbacks; } return; } } callback(geoInfo); }
public void LoadCache() { if (!File.Exists(this.cacheFile)) { return; } lock (cache) { foreach (var line in File.ReadAllLines(this.cacheFile)) { try { var parts = line.Split(new[] { '=' }, 2); uint ipInt = 0; var octets = parts[0].Split('.'); foreach (var octet in octets) { ipInt = (ipInt << 8) + uint.Parse(octet); } var loc = parts[1].Split('|'); var countryCode = loc[0]; var latitude = decimal.Parse(loc[5], NumberFormatInfo.InvariantInfo); var longitude = decimal.Parse(loc[6], NumberFormatInfo.InvariantInfo); if (countryCode != "") { var geoInfo = new GeoInfo(countryCode, loc[1], loc[2], loc[3], loc[4], latitude, longitude); cache[ipInt] = geoInfo; } } catch { // ignore } } // override wrong geo-IP information (MS Azure IPs list Washington even for NL/EU servers) cache[Ip4Utils.ToInt(104, 40, 134, 97)] = new GeoInfo("NL", "Netherlands", null, null, null, 0, 0); cache[Ip4Utils.ToInt(104, 40, 213, 215)] = new GeoInfo("NL", "Netherlands", null, null, null, 0, 0); // Vultr also spreads their IPs everywhere cache[Ip4Utils.ToInt(45, 32, 153, 115)] = new GeoInfo("DE", "Germany", null, null, null, 0, 0); // listed as NL, but is DE cache[Ip4Utils.ToInt(45, 32, 205, 149)] = new GeoInfo("US", "United States", "TX", null, null, 0, 0); // listed as NL, but is TX // i3d.net cache[Ip4Utils.ToInt(185, 179, 200, 69)] = new GeoInfo("ZA", "South Africa", null, null, null, 0, 0); // listed as NL, but is ZA } }
private GeoInfo HandleResult(uint ip, string result) { var ser = new DataContractJsonSerializer(typeof(NekudoGeopIpFullResponse)); var info = (NekudoGeopIpFullResponse)ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(result))); var subdiv = info.subdivisions?[info.subdivisions.Length - 1]; var geoInfo = new GeoInfo( info.country?.iso_code, TryGet(info.country?.names, "en"), subdiv?.iso_code, TryGet(subdiv?.names, "en"), TryGet(info.city?.names, "en"), info.location?.latitude ?? 0, info.location?.longitude ?? 0); lock (cache) { cache[ip] = geoInfo; } return(geoInfo); }
private GeoInfo HandleResult(uint ip, string result) { var ser = new DataContractJsonSerializer(typeof(NekudoGeopIpFullResponse)); var info = (NekudoGeopIpFullResponse)ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(result))); if (!info.success) { if (info.error?.code == 104) { this.usageExceeded = DateTime.UtcNow.Date; } lock (cache) this.cache.Remove(ip); return(null); } var geoInfo = new GeoInfo(info.country_code, info.country_name, info.region_code, info.region_name, info.city, info.latitude, info.longitude); lock (cache) { cache[ip] = geoInfo; } return(geoInfo); }