2023-12-10 16:30:43 +00:00
|
|
|
package nu.marginalia.geoip;
|
2023-12-09 19:04:27 +00:00
|
|
|
|
|
|
|
import nu.marginalia.WmsaHome;
|
2023-12-17 14:03:00 +00:00
|
|
|
import nu.marginalia.geoip.sources.AsnMapping;
|
|
|
|
import nu.marginalia.geoip.sources.AsnTable;
|
|
|
|
import nu.marginalia.geoip.sources.IP2LocationMapping;
|
2023-12-09 19:04:27 +00:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
import java.net.InetAddress;
|
2023-12-16 20:55:04 +00:00
|
|
|
import java.util.Optional;
|
2023-12-09 19:04:27 +00:00
|
|
|
|
|
|
|
public class GeoIpDictionary {
|
2023-12-17 14:03:00 +00:00
|
|
|
private volatile IP2LocationMapping ip2locMapping = null;
|
2023-12-16 20:55:04 +00:00
|
|
|
private volatile AsnTable asnTable = null;
|
|
|
|
private volatile AsnMapping asnMapping = null;
|
2023-12-09 19:04:27 +00:00
|
|
|
private static final Logger logger = LoggerFactory.getLogger(GeoIpDictionary.class);
|
|
|
|
|
2023-12-17 14:03:00 +00:00
|
|
|
volatile boolean ready = false;
|
2023-12-09 19:04:27 +00:00
|
|
|
|
|
|
|
public GeoIpDictionary() {
|
|
|
|
Thread.ofPlatform().start(() -> {
|
2023-12-16 20:55:04 +00:00
|
|
|
this.asnTable = new AsnTable(WmsaHome.getAsnInfoDatabase());
|
|
|
|
logger.info("Loaded ASN table");
|
|
|
|
this.asnMapping = new AsnMapping(WmsaHome.getAsnMappingDatabase());
|
|
|
|
logger.info("Loaded ASN mapping");
|
2023-12-17 14:03:00 +00:00
|
|
|
this.ip2locMapping = new IP2LocationMapping(WmsaHome.getIPLocationDatabse());
|
|
|
|
|
|
|
|
ready = true;
|
|
|
|
|
|
|
|
synchronized (this) {
|
|
|
|
this.notifyAll();
|
|
|
|
}
|
2023-12-09 19:04:27 +00:00
|
|
|
});
|
2023-12-10 16:30:43 +00:00
|
|
|
}
|
2023-12-09 19:04:27 +00:00
|
|
|
|
2023-12-10 16:30:43 +00:00
|
|
|
public boolean isReady() {
|
2023-12-17 14:03:00 +00:00
|
|
|
return ready;
|
2023-12-10 16:30:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean waitReady() {
|
2023-12-17 14:03:00 +00:00
|
|
|
while (!ready) {
|
2023-12-10 16:30:43 +00:00
|
|
|
try {
|
2023-12-11 13:01:39 +00:00
|
|
|
synchronized (this) {
|
|
|
|
this.wait(1000);
|
|
|
|
}
|
2023-12-10 16:30:43 +00:00
|
|
|
} catch (InterruptedException e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2023-12-09 19:04:27 +00:00
|
|
|
}
|
|
|
|
|
2023-12-17 14:03:00 +00:00
|
|
|
|
|
|
|
public String getCountry(String ip) {
|
|
|
|
if (null == ip2locMapping) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return ip2locMapping.getCountry(ip);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getCountry(InetAddress address) {
|
|
|
|
if (null == ip2locMapping) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
return ip2locMapping.getCountry(address);
|
|
|
|
}
|
|
|
|
|
2023-12-16 20:55:04 +00:00
|
|
|
public Optional<AsnTable.AsnInfo> getAsnInfo(String ip) {
|
2023-12-09 19:04:27 +00:00
|
|
|
try {
|
2023-12-16 20:55:04 +00:00
|
|
|
return getAsnInfo(InetAddress.getByName(ip));
|
2023-12-09 19:04:27 +00:00
|
|
|
} catch (Exception e) {
|
2023-12-16 20:55:04 +00:00
|
|
|
e.printStackTrace();
|
|
|
|
return Optional.empty();
|
2023-12-09 19:04:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-16 20:55:04 +00:00
|
|
|
public Optional<AsnTable.AsnInfo> getAsnInfo(int ipAddress) {
|
|
|
|
if (null == asnTable) { // not loaded yet or failed to load
|
|
|
|
return Optional.empty();
|
2023-12-09 19:04:27 +00:00
|
|
|
}
|
|
|
|
|
2023-12-16 20:55:04 +00:00
|
|
|
return asnMapping
|
|
|
|
.getAsnNumber(ipAddress)
|
|
|
|
.flatMap(asn -> asnTable.getAsnInfo(asn));
|
|
|
|
}
|
2023-12-09 19:04:27 +00:00
|
|
|
|
2023-12-16 20:55:04 +00:00
|
|
|
public Optional<AsnTable.AsnInfo> getAsnInfo(InetAddress address) {
|
|
|
|
byte[] bytes = address.getAddress();
|
2023-12-09 19:04:27 +00:00
|
|
|
|
2023-12-16 20:55:04 +00:00
|
|
|
int ival = (int) (((long)bytes[0]&0xFF) << 24 | ((long)bytes[1]&0xFF) << 16 | ((long)bytes[2]&0xFF)<< 8 | ((long)bytes[3]&0xFF));
|
2023-12-09 19:04:27 +00:00
|
|
|
|
2023-12-16 20:55:04 +00:00
|
|
|
return getAsnInfo(ival);
|
2023-12-09 19:04:27 +00:00
|
|
|
}
|
|
|
|
}
|